text.lib.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. <?php // $Id: text.lib.php 20709 2009-05-15 19:12:37Z ivantcholakov $
  2. /* For licensing terms, see /dokeos_license.txt */
  3. /**
  4. ==============================================================================
  5. * This is the text library for Dokeos.
  6. * Include/require it in your code to use its functionality.
  7. *
  8. * @package dokeos.library
  9. ==============================================================================
  10. */
  11. /*
  12. ==============================================================================
  13. FUNCTIONS
  14. ==============================================================================
  15. */
  16. /**
  17. * function make_clickable($string)
  18. *
  19. * @desc completes url contained in the text with "<a href ...".
  20. * However the function simply returns the submitted text without any
  21. * transformation if it already contains some "<a href:" or "<img src=".
  22. * @param string $text text to be converted
  23. * @return text after conversion
  24. * @author Rewritten by Nathan Codding - Feb 6, 2001.
  25. * completed by Hugues Peeters - July 22, 2002
  26. *
  27. * Actually this function is taken from the PHP BB 1.4 script
  28. * - Goes through the given string, and replaces xxxx://yyyy with an HTML <a> tag linking
  29. * to that URL
  30. * - Goes through the given string, and replaces www.xxxx.yyyy[zzzz] with an HTML <a> tag linking
  31. * to http://www.xxxx.yyyy[/zzzz]
  32. * - Goes through the given string, and replaces xxxx@yyyy with an HTML mailto: tag linking
  33. * to that email address
  34. * - Only matches these 2 patterns either after a space, or at the beginning of a line
  35. *
  36. * Notes: the email one might get annoying - it's easy to make it more restrictive, though.. maybe
  37. * have it require something like xxxx@yyyy.zzzz or such. We'll see.
  38. */
  39. function make_clickable($string)
  40. {
  41. if(!stristr($string,' src=') && !stristr($string,' href='))
  42. {
  43. $string=eregi_replace("(https?|ftp)://([a-z0-9#?/&=._+:~%-]+)","<a href=\"\\1://\\2\" target=\"_blank\">\\1://\\2</a>",$string);
  44. $string=eregi_replace("([a-z0-9_.-]+@[a-z0-9.-]+)","<a href=\"mailto:\\1\">\\1</a>",$string);
  45. }
  46. return $string;
  47. }
  48. /**
  49. * formats the date according to the locale settings
  50. *
  51. * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
  52. * @author Christophe Gesch� <gesche@ipm.ucl.ac.be>
  53. * originally inspired from from PhpMyAdmin
  54. * @param string $date_format date pattern
  55. * @param integer $time_stamp, default is NOW.
  56. * @return the formatted date
  57. */
  58. function format_locale_date($date_format, $time_stamp = -1)
  59. {
  60. static $initialized = false;
  61. static $days_short, $days_long, $months_short, $months_long;
  62. if (!$initialized)
  63. {
  64. // Defining the shorts for the days
  65. $days_short = array (get_lang("SundayShort"), get_lang("MondayShort"), get_lang("TuesdayShort"), get_lang("WednesdayShort"), get_lang("ThursdayShort"), get_lang("FridayShort"), get_lang("SaturdayShort"));
  66. // Defining the days of the week to allow translation of the days
  67. $days_long = array (get_lang("SundayLong"), get_lang("MondayLong"), get_lang("TuesdayLong"), get_lang("WednesdayLong"), get_lang("ThursdayLong"), get_lang("FridayLong"), get_lang("SaturdayLong"));
  68. // Defining the shorts for the months
  69. $months_short = array (get_lang("JanuaryShort"), get_lang("FebruaryShort"), get_lang("MarchShort"), get_lang("AprilShort"), get_lang("MayShort"), get_lang("JuneShort"), get_lang("JulyShort"), get_lang("AugustShort"), get_lang("SeptemberShort"), get_lang("OctoberShort"), get_lang("NovemberShort"), get_lang("DecemberShort"));
  70. // Defining the months of the year to allow translation of the months
  71. $months_long = array (get_lang("JanuaryLong"), get_lang("FebruaryLong"), get_lang("MarchLong"), get_lang("AprilLong"), get_lang("MayLong"), get_lang("JuneLong"), get_lang("JulyLong"), get_lang("AugustLong"), get_lang("SeptemberLong"), get_lang("OctoberLong"), get_lang("NovemberLong"), get_lang("DecemberLong"));
  72. $initialized = true;
  73. }
  74. if ($time_stamp == -1) $time_stamp = time();
  75. // with the ereg we replace %aAbB of date format
  76. //(they can be done by the system when locale date aren't aivailable
  77. $date = ereg_replace('%[A]', $days_long[(int)strftime('%w', $time_stamp)], $date_format);
  78. $date = ereg_replace('%[a]', $days_short[(int)strftime('%w', $time_stamp)], $date);
  79. $date = ereg_replace('%[B]', $months_long[(int)strftime('%m', $time_stamp)-1], $date);
  80. $date = ereg_replace('%[b]', $months_short[(int)strftime('%m', $time_stamp)-1], $date);
  81. return strftime($date, $time_stamp);
  82. } // end function format_locale_date
  83. /**
  84. * @desc this function does some parsing on the text that gets inputted. This parsing can be of any kind
  85. * LaTeX notation, Word Censoring, Glossary Terminology (extension will available soon), Musical Notations, ...
  86. * The inspiration for this filter function came from Moodle an phpBB who both use a similar approach
  87. * @param $input string. some text
  88. * @return $output string. some text that contains the parsed elements.
  89. * @example [tex]\sqrt(2)[/tex]
  90. * @author Patrick Cool <patrick.cool@UGent.be>
  91. * @version March 2OO6
  92. */
  93. function text_filter($input, $filter=true)
  94. {
  95. //$input=stripslashes($input);
  96. if ($filter==true)
  97. {
  98. // *** parse [tex]...[/tex] tags *** //
  99. // which will return techexplorer or image html depending on the capabilities of the
  100. // browser of the user (using some javascript that checks if the browser has the TechExplorer plugin installed or not)
  101. $input=_text_parse_tex($input);
  102. // *** parse [teximage]...[/teximage] tags *** //
  103. // these force the gif rendering of LaTeX using the mimetex gif renderer
  104. //$input=_text_parse_tex_image($input);
  105. // *** parse [texexplorer]...[/texexplorer] tags *** //
  106. // these force the texeplorer LaTeX notation
  107. $input=_text_parse_texexplorer($input);
  108. // *** Censor Words *** //
  109. // censor words. This function removes certain words by [censored]
  110. // this can be usefull when the campus is open to the world.
  111. // $input=text_censor_words($input);
  112. // *** parse [?]...[/?] tags *** //
  113. // for the glossary tool (see http://www.dokeos.com/extensions)
  114. $input=_text_parse_glossary($input);
  115. // parse [wiki]...[/wiki] tags
  116. // this is for the coolwiki plugin.
  117. // $input=text_parse_wiki($input);
  118. // parse [tool]...[/tool] tags
  119. // this parse function adds a link to a certain tool
  120. // $input=text_parse_tool($input);
  121. // parse [user]...[/user] tags
  122. // parse [email]...[/email] tags
  123. // parse [code]...[/code] tags
  124. }
  125. return $input;
  126. }
  127. /**
  128. * Apply parsing to content to parse tex commandos that are seperated by [tex]
  129. * [/tex] to make it readable for techexplorer plugin.
  130. * This function should not be accessed directly but should be accesse through the text_filter function
  131. * @param string $text The text to parse
  132. * @return string The text after parsing.
  133. * @author Patrick Cool <patrick.cool@UGent.be>
  134. * @version June 2004
  135. */
  136. function _text_parse_tex($textext)
  137. {
  138. //$textext = str_replace(array ("[tex]", "[/tex]"), array ('[*****]', '[/*****]'), $textext);
  139. //$textext=stripslashes($texttext);
  140. $input_array=preg_split("/(\[tex]|\[\/tex])/",$textext,-1, PREG_SPLIT_DELIM_CAPTURE);
  141. foreach ($input_array as $key=>$value)
  142. {
  143. if ($key>0 && $input_array[$key-1]=='[tex]' AND $input_array[$key+1]=='[/tex]')
  144. {
  145. $input_array[$key]=latex_gif_renderer($value);
  146. unset($input_array[$key-1]);
  147. unset($input_array[$key+1]);
  148. //echo 'LaTeX: <embed type="application/x-techexplorer" texdata="'.stripslashes($value).'" autosize="true" pluginspage="http://www.integretechpub.com/techexplorer/"><br />';
  149. }
  150. }
  151. $output=implode('',$input_array);
  152. return $output;
  153. }
  154. /**
  155. * Apply parsing to content to parse tex commandos that are seperated by [tex]
  156. * [/tex] to make it readable for techexplorer plugin.
  157. * This function should not be accessed directly but should be accesse through the text_filter function
  158. * @param string $text The text to parse
  159. * @return string The text after parsing.
  160. * @author Patrick Cool <patrick.cool@UGent.be>
  161. * @version June 2004
  162. */
  163. function _text_parse_texexplorer($textext)
  164. {
  165. if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE'))
  166. {
  167. $textext = str_replace(array ("[texexplorer]", "[/texexplorer]"), array ("<object classid=\"clsid:5AFAB315-AD87-11D3-98BB-002035EFB1A4\"><param name=\"autosize\" value=\"true\" /><param name=\"DataType\" value=\"0\" /><param name=\"Data\" value=\"", "\" /></object>"), $textext);
  168. }
  169. else
  170. {
  171. $textext = str_replace(array ("[texexplorer]", "[/texexplorer]"), array ("<embed type=\"application/x-techexplorer\" texdata=\"", "\" autosize=\"true\" pluginspage=\"http://www.integretechpub.com/techexplorer/\">"), $textext);
  172. }
  173. return $textext;
  174. }
  175. /**
  176. * This function should not be accessed directly but should be accesse through the text_filter function
  177. * @author Patrick Cool <patrick.cool@UGent.be>
  178. */
  179. function _text_parse_glossary($input)
  180. {
  181. return $input;
  182. }
  183. /**
  184. * @desc this function makes a valid link to a different tool
  185. * This function should not be accessed directly but should be accesse through the text_filter function
  186. * @author Patrick Cool <patrick.cool@UGent.be>
  187. */
  188. function _text_parse_tool($input)
  189. {
  190. // an array with all the valid tools
  191. $tools[]=array(TOOL_ANNOUNCEMENT, 'announcements/announcements.php');
  192. $tools[]=array(TOOL_CALENDAR_EVENT, 'calendar/agenda.php');
  193. // check if the name between the [tool] [/tool] tags is a valid one
  194. }
  195. /**
  196. * render LaTeX code into a gif or retrieve a cached version of the gif
  197. * @author Patrick Cool <patrick.cool@UGent.be> Ghent University
  198. */
  199. function latex_gif_renderer($latex_code)
  200. {
  201. global $_course;
  202. // setting the paths and filenames
  203. $mimetex_path=api_get_path(LIBRARY_PATH).'mimetex/';
  204. $temp_path=api_get_path(SYS_COURSE_PATH).$_course['path'].'/temp/';
  205. $latex_filename=md5($latex_code).'.gif';
  206. if(!file_exists($temp_path.$latex_filename) OR isset($_GET['render']))
  207. {
  208. if ((PHP_OS == "WINNT") || (PHP_OS == "WIN32") || (PHP_OS == "Windows"))
  209. {
  210. $mimetex_command=$mimetex_path.'mimetex.exe -e "'.$temp_path.md5($latex_code).'.gif" '.escapeshellarg($latex_code).'';
  211. }
  212. else
  213. {
  214. $mimetex_command=$mimetex_path.'mimetex.linux -e "'.$temp_path.md5($latex_code).'.gif" '.escapeshellarg($latex_code);
  215. }
  216. exec($mimetex_command);
  217. //echo 'volgende shell commando werd uitgevoerd:<br /><pre>'.$mimetex_command.'</pre><hr>';
  218. }
  219. $return = "<a href=\"\" onclick=\"newWindow=window.open('".api_get_path(WEB_CODE_PATH)."inc/latex.php?code=".urlencode($latex_code)."&amp;filename=$latex_filename','latexCode','toolbar=no,location=no,scrollbars=yes,resizable=yes,status=yes,width=375,height=250,left=200,top=100');\">";
  220. $return .= '<img src="'.api_get_path(WEB_COURSE_PATH).$_course['path'].'/temp/'.$latex_filename.'" alt="'.$latex_code.'" border="0" /></a>';
  221. return $return;
  222. }
  223. /**
  224. * Returns the difference between the current date (date(now)) with the parameter $date in a string format like "2 days, 1 hour"
  225. * Example: $date="2008-03-07 15:44:08";
  226. * date_to_str($date) it will return 3 days, 20 hours
  227. *
  228. * @param string The string has to be the result of a date function in this format -> date("Y-m-d H:i:s",time());
  229. * @return string The difference between the current date and the parameter in a literal way "3 days, 2 hour" *
  230. * @author Julio Montoya
  231. */
  232. function date_to_str_ago($date)
  233. {
  234. static $initialized = false;
  235. static $today, $yesterday;
  236. static $min_decade, $min_year, $min_month, $min_week, $min_day, $min_hour, $min_minute;
  237. static $min_decades, $min_years, $min_months, $min_weeks, $min_days, $min_hours, $min_minutes;
  238. static $sec_time_time, $sec_time_sing, $sec_time_plu;
  239. if (!$initialized) {
  240. $today = api_ucfirst(get_lang('Today'));
  241. $yesterday = api_ucfirst(get_lang('Yesterday'));
  242. $min_decade=get_lang('MinDecade');
  243. $min_year=get_lang('MinYear');
  244. $min_month=get_lang('MinMonth');
  245. $min_week=get_lang('MinWeek');
  246. $min_day=get_lang('MinDay');
  247. $min_hour=get_lang('MinHour');
  248. $min_minute=get_lang('MinMinute');
  249. $min_decades=get_lang('MinDecades');
  250. $min_years=get_lang('MinYears');
  251. $min_months=get_lang('MinMonths');
  252. $min_weeks=get_lang('MinWeeks');
  253. $min_days=get_lang('MinDays');
  254. $min_hours=get_lang('MinHours');
  255. $min_minutes=get_lang('MinMinutes');
  256. // original 1
  257. //$sec_time=array("century"=>3.1556926*pow(10,9),"decade"=>315569260,"year"=>31556926,"month"=>2629743.83,"week"=>604800,"day"=>86400,"hour"=>3600,"minute"=>60,"second"=>1);
  258. //$sec_time=array(get_lang('MinDecade')=>315569260,get_lang('MinYear')=>31556926,get_lang('MinMonth')=>2629743.83,get_lang('MinWeek')=>604800,get_lang('MinDay')=>86400,get_lang('MinHour')=>3600,get_lang('MinMinute')=>60);
  259. $sec_time_time=array(315569260,31556926,2629743.83,604800,86400,3600,60);
  260. $sec_time_sing=array($min_decade,$min_year,$min_month,$min_week,$min_day,$min_hour,$min_minute);
  261. $sec_time_plu =array($min_decades,$min_years,$min_months,$min_weeks,$min_days,$min_hours,$min_minutes);
  262. $initialized = true;
  263. }
  264. $dst_date=strtotime($date);
  265. //for not call date several times
  266. $date_array=date("s/i/G/j/n/Y",$dst_date);
  267. $date_split=explode("/",$date_array);
  268. $dst_s=$date_split[0];
  269. $dst_m=$date_split[1];
  270. $dst_h=$date_split[2];
  271. $dst_day=$date_split[3];
  272. $dst_mth=$date_split[4];
  273. $dst_yr=$date_split[5];
  274. $dst_date = mktime($dst_h,$dst_m,$dst_s,$dst_mth,$dst_day,$dst_yr);
  275. $time=$offset = time()-$dst_date; //seconds between current days and today
  276. //------------ Here start the functions sec_to_str
  277. $act_day=date('d');
  278. $act_mth=date('n');
  279. $act_yr = date('Y');
  280. if ($dst_day==$act_day && $dst_mth==$act_mth && $dst_yr == $act_yr ) {
  281. return $today;
  282. }
  283. if ($dst_day==$act_day-1 && $dst_mth==$act_mth && $dst_yr == $act_yr ) {
  284. return $yesterday;
  285. }
  286. $str_result=array();
  287. $time_result=array();
  288. $key_result=array();
  289. $str='';
  290. $i=0;
  291. for ($i=0;$i<count($sec_time_time);$i++) {
  292. $seconds=$sec_time_time[$i];
  293. if($seconds > $time) {
  294. continue;
  295. }
  296. $current_value=intval($time/$seconds);
  297. if ($current_value != 1) {
  298. $date_str= $sec_time_plu[$i];
  299. } else {
  300. $date_str= $sec_time_sing[$i];
  301. }
  302. $key_result[]=$sec_time_sing[$i];
  303. $str_result[]=$current_value.' '.$date_str;
  304. $time_result[]= $current_value;
  305. $str.=$current_value.$date_str;
  306. $time%=$seconds;
  307. }
  308. if ($key_result[0]== $min_day && $key_result[1]== $min_minute) {
  309. $key_result[1]=' 0 '.$min_hours;
  310. $str_result[0]=$time_result[0].' '.$key_result[0];
  311. $str_result[1]=$key_result[1];
  312. }
  313. if ($key_result[0]== $min_year && ($key_result[1]== $min_day || $key_result[1]== $min_week)) {
  314. $key_result[1]=' 0 '.$min_months;
  315. $str_result[0]=$time_result[0].' '.$key_result[0];
  316. $str_result[1]=$key_result[1];
  317. }
  318. if (!empty($str_result[1])) {
  319. $str=$str_result[0].', '.$str_result[1];
  320. } else {
  321. $str=$str_result[0];
  322. }
  323. return $str;
  324. }
  325. /**
  326. * This functions cuts a paragraph
  327. * i.e cut('Merry Xmas from Lima',13) = "Merry Xmas fr..."
  328. * @param string the text to "cut"
  329. * @param int count of chars
  330. * @param bool Whether to embed in a <span title="...">...</span>
  331. * @return string
  332. * */
  333. function cut($text,$maxchar,$embed=false)
  334. {
  335. if (api_strlen($text) > $maxchar) {
  336. if ($embed==true) {
  337. return '<span title="'.$text.'">'.api_substr($text, 0, $maxchar).'...</span>';
  338. }
  339. return api_substr($text, 0, $maxchar).'...' ;
  340. } else {
  341. return $text;
  342. }
  343. }
  344. /**
  345. * Show a number as only integers if no decimals, but will show 2 decimals if exist.
  346. *
  347. * @param mixed number to convert
  348. * @param int decimal points 0=never, 1=if needed, 2=always
  349. * @return mixed an integer or a float depends on the parameter
  350. */
  351. function float_format($number, $flag = 1)
  352. {
  353. if (is_numeric($number)) { // a number
  354. if (!$number) { // zero
  355. $result = ($flag == 2 ? '0.00' : '0'); // output zero
  356. } else { // value
  357. if (floor($number) == $number) { // whole number
  358. $result = number_format($number, ($flag == 2 ? 2 : 0)); // format
  359. } else { // cents
  360. $result = number_format(round($number, 2), ($flag == 0 ? 0 : 2)); // format
  361. } // integer or decimal
  362. } // value
  363. return $result;
  364. }
  365. }
  366. ?>