fckeditor.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. <?php
  2. /*
  3. * FCKeditor - The text editor for Internet - http://www.fckeditor.net
  4. * Copyright (C) 2003-2010 Frederico Caldeira Knabben
  5. *
  6. * == BEGIN LICENSE ==
  7. *
  8. * Licensed under the terms of any of the following licenses at your
  9. * choice:
  10. *
  11. * - GNU General Public License Version 2 or later (the "GPL")
  12. * http://www.gnu.org/licenses/gpl.html
  13. *
  14. * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
  15. * http://www.gnu.org/licenses/lgpl.html
  16. *
  17. * - Mozilla Public License Version 1.1 or later (the "MPL")
  18. * http://www.mozilla.org/MPL/MPL-1.1.html
  19. *
  20. * == END LICENSE ==
  21. *
  22. * This is the integration file for PHP 5.
  23. *
  24. * It defines the FCKeditor class that can be used to create editor
  25. * instances in PHP pages on server side.
  26. */
  27. // Code about adaptation of the editor and its plugins has been added by the Chamilo team, 2009-2010.
  28. // For modifying configuration options see myconfig.php and myconfig.js.
  29. /**
  30. * Check if browser is compatible with FCKeditor.
  31. * Return true if is compatible.
  32. *
  33. * @return boolean
  34. */
  35. function FCKeditor_IsCompatibleBrowser()
  36. {
  37. if ( isset( $_SERVER ) ) {
  38. $sAgent = $_SERVER['HTTP_USER_AGENT'] ;
  39. } else {
  40. global $HTTP_SERVER_VARS ;
  41. if ( isset( $HTTP_SERVER_VARS ) ) {
  42. $sAgent = $HTTP_SERVER_VARS['HTTP_USER_AGENT'] ;
  43. }
  44. else {
  45. global $HTTP_USER_AGENT ;
  46. $sAgent = $HTTP_USER_AGENT ;
  47. }
  48. }
  49. if ( strpos($sAgent, 'MSIE') !== false && strpos($sAgent, 'mac') === false && strpos($sAgent, 'Opera') === false ) {
  50. $iVersion = (float)substr($sAgent, strpos($sAgent, 'MSIE') + 5, 3) ;
  51. return ($iVersion >= 5.5) ;
  52. } else if ( strpos($sAgent, 'Gecko/') !== false ) {
  53. $iVersion = substr($sAgent, strpos($sAgent, 'Gecko/') + 6, 8) ;
  54. // Special fix for Firefox 17 and followers - see #5752
  55. if ( preg_match('/^\d{2,3}\.\d{1,4}\s/', $iVersion) ) {
  56. return true;
  57. }
  58. $iVersion = (int)$iVersion;
  59. //return ($iVersion >= 20030210) ;
  60. return true;
  61. } else if ( strpos($sAgent, 'Opera/') !== false ) {
  62. $fVersion = (float)substr($sAgent, strpos($sAgent, 'Opera/') + 6, 4) ;
  63. return ($fVersion >= 9.5) ;
  64. } else if ( preg_match( "|AppleWebKit/(\d+)|i", $sAgent, $matches ) ) {
  65. $iVersion = $matches[1] ;
  66. return ( $matches[1] >= 522 ) ;
  67. } else if ( strpos($sAgent, 'Gecko') !== false && strpos($sAgent, 'rv:') !== false ) {
  68. // General match for IE11
  69. if (strpos($sAgent, 'Chrome') !== false) {
  70. // Chrome 34 under Ubuntu might have a rv: of <11
  71. return true;
  72. }
  73. // Internet Explorer 11 - goes with a X-UA-Compatible IE=EmulateIE9 header
  74. $iVersion = (int)substr($sAgent, strpos($sAgent, 'rv:') + 3, 2) ;
  75. return ($iVersion >= 11);
  76. } else {
  77. return false ;
  78. }
  79. }
  80. class FCKeditor
  81. {
  82. /**
  83. * Name of the FCKeditor instance.
  84. *
  85. * @access protected
  86. * @var string
  87. */
  88. public $InstanceName ;
  89. /**
  90. * Path to FCKeditor relative to the document root.
  91. *
  92. * @var string
  93. */
  94. public $BasePath ;
  95. /**
  96. * Width of the FCKeditor.
  97. * Examples: 100%, 600
  98. *
  99. * @var mixed
  100. */
  101. public $Width ;
  102. /**
  103. * Height of the FCKeditor.
  104. * Examples: 400, 50%
  105. *
  106. * @var mixed
  107. */
  108. public $Height ;
  109. /**
  110. * Name of the toolbar to load.
  111. *
  112. * @var string
  113. */
  114. public $ToolbarSet ;
  115. /**
  116. * Initial value.
  117. *
  118. * @var string
  119. */
  120. public $Value ;
  121. /**
  122. * This is where additional configuration can be passed.
  123. * Example:
  124. * $oFCKeditor->Config['EnterMode'] = 'br';
  125. *
  126. * @var array
  127. */
  128. public $Config ;
  129. /**
  130. * Main Constructor.
  131. * Refer to the _samples/php directory for examples.
  132. *
  133. * @param string $instanceName
  134. */
  135. public function __construct( $instanceName )
  136. {
  137. $this->InstanceName = $instanceName ;
  138. $this->BasePath = '/fckeditor/' ;
  139. $this->Width = '100%' ;
  140. $this->Height = '200' ;
  141. $this->ToolbarSet = 'Default' ;
  142. $this->Value = '' ;
  143. $this->Config = array() ;
  144. }
  145. /**
  146. * Display FCKeditor.
  147. *
  148. */
  149. public function Create()
  150. {
  151. echo $this->CreateHtml() ;
  152. }
  153. /**
  154. * Return the HTML code required to run FCKeditor.
  155. *
  156. * @return string
  157. */
  158. public function CreateHtml()
  159. {
  160. // Adaptation for the Chamilo LMS
  161. //@todo why the BasePath is relative ? we should use this constant WEB_PATH
  162. $this->BasePath = api_get_path(REL_PATH).'main/inc/lib/fckeditor/';
  163. $config = $this->get_custom_configuration();
  164. $this->read_configuration($config);
  165. $config = $this->get_default_configuration();
  166. $this->read_configuration($config);
  167. if ((api_is_allowed_to_edit() || api_is_platform_admin()) && isset($this->Config['BlockCopyPaste'])) {
  168. $this->Config['BlockCopyPaste'] = false;
  169. }
  170. $HtmlValue = htmlspecialchars( $this->Value ) ;
  171. $Html = '' ;
  172. if ( FCKeditor::IsCompatible() ) {
  173. if ( api_get_setting('server_type') == 'test' )
  174. $File = 'fckeditor.original.html' ;
  175. else
  176. $File = 'fckeditor.html' ;
  177. $Link = "{$this->BasePath}editor/{$File}?InstanceName={$this->InstanceName}" ;
  178. if ( $this->ToolbarSet != '' )
  179. $Link .= "&amp;Toolbar={$this->ToolbarSet}" ;
  180. // Render the linked hidden field.
  181. $Html .= "<input type=\"hidden\" id=\"{$this->InstanceName}\" name=\"{$this->InstanceName}\" value=\"{$HtmlValue}\" style=\"display:none\" />" ;
  182. // Render the configurations hidden field.
  183. $Html .= "<input type=\"hidden\" id=\"{$this->InstanceName}___Config\" value=\"" . $this->GetConfigFieldString() . "\" style=\"display:none\" />" ;
  184. // Render the editor IFRAME.
  185. $Html .= "<iframe id=\"{$this->InstanceName}___Frame\" src=\"{$Link}\" width=\"{$this->Width}\" height=\"{$this->Height}\" frameborder=\"0\" scrolling=\"no\"></iframe>" ;
  186. } else {
  187. if ( strpos( $this->Width, '%' ) === false )
  188. $WidthCSS = $this->Width . 'px' ;
  189. else
  190. $WidthCSS = $this->Width ;
  191. if ( strpos( $this->Height, '%' ) === false )
  192. $HeightCSS = $this->Height . 'px' ;
  193. else
  194. $HeightCSS = $this->Height ;
  195. $Html .= "<textarea name=\"{$this->InstanceName}\" rows=\"4\" cols=\"40\" style=\"width: {$WidthCSS}; height: {$HeightCSS}\">{$HtmlValue}</textarea>" ;
  196. }
  197. return $Html ;
  198. }
  199. /**
  200. * Returns true if browser is compatible with FCKeditor.
  201. *
  202. * @return boolean
  203. */
  204. public static function IsCompatible()
  205. {
  206. return FCKeditor_IsCompatibleBrowser() ;
  207. }
  208. /**
  209. * Get settings from Config array as a single string.
  210. *
  211. * @access protected
  212. * @return string
  213. */
  214. public function GetConfigFieldString()
  215. {
  216. $sParams = '' ;
  217. $bFirst = true ;
  218. foreach ( $this->Config as $sKey => $sValue )
  219. {
  220. if ( !$bFirst ) {
  221. $sParams .= '&amp;' ;
  222. } else {
  223. $bFirst = false ;
  224. }
  225. if ( is_string( $sValue ) ) {
  226. $sParams .= $this->EncodeConfig( $sKey ) . '=' . $this->EncodeConfig( $sValue ) ;
  227. } else {
  228. $sParams .= $this->EncodeConfig( $sKey ) . '=' . $this->EncodeConfig( $this->to_js( $sValue ) ) ;
  229. }
  230. }
  231. return $sParams ;
  232. }
  233. /**
  234. * Encode characters that may break the configuration string
  235. * generated by GetConfigFieldString().
  236. *
  237. * @access protected
  238. * @param string $valueToEncode
  239. * @return string
  240. */
  241. public function EncodeConfig( $valueToEncode )
  242. {
  243. $chars = array(
  244. '&' => '%26',
  245. '=' => '%3D',
  246. '"' => '%22',
  247. '%' => '%25'
  248. ) ;
  249. return strtr( $valueToEncode, $chars ) ;
  250. }
  251. /**
  252. * Converts a PHP variable into its Javascript equivalent.
  253. * The code of this method has been "borrowed" from the funcion drupal_to_js() within the Drupal CMS.
  254. * @param mixed $var The variable to be converted into Javascript syntax
  255. * @return string Returns a string
  256. * Note: This function is similar to json_encode(), in addition it produces HTML-safe strings, i.e. with <, > and & escaped.
  257. * @link http://drupal.org/
  258. */
  259. private function to_js( $var ) {
  260. switch ( gettype( $var ) ) {
  261. case 'boolean' :
  262. return $var ? 'true' : 'false' ; // Lowercase necessary!
  263. case 'integer' :
  264. case 'double' :
  265. return (string) $var ;
  266. case 'resource' :
  267. case 'string' :
  268. return '"' . str_replace( array( "\r", "\n", "<", ">", "&" ), array( '\r', '\n', '\x3c', '\x3e', '\x26' ), addslashes( $var ) ) . '"' ;
  269. case 'array' :
  270. // Arrays in JSON can't be associative. If the array is empty or if it
  271. // has sequential whole number keys starting with 0, it's not associative
  272. // so we can go ahead and convert it as an array.
  273. if ( empty( $var ) || array_keys( $var ) === range( 0, sizeof( $var ) - 1 ) ) {
  274. $output = array() ;
  275. foreach ( $var as $v ) {
  276. $output[] = $this->to_js( $v ) ;
  277. }
  278. return '[ ' . implode( ', ', $output ) . ' ]' ;
  279. }
  280. // Otherwise, fall through to convert the array as an object.
  281. case 'object' :
  282. $output = array() ;
  283. foreach ( $var as $k => $v ) {
  284. $output[] = $this->to_js( strval( $k ) ) . ': ' . $this->to_js( $v ) ;
  285. }
  286. return '{ ' . implode(', ', $output) . ' }' ;
  287. default:
  288. return 'null' ;
  289. }
  290. }
  291. /**
  292. * This method reads configuration data for the current editor's instance without overriding settings that already exist.
  293. * @return array
  294. */
  295. function read_configuration(& $config) {
  296. $toolbar_set = $this->ToolbarSet;
  297. $toolbar_set_maximized = $this->ToolbarSet.'Maximized';
  298. foreach ($config as $key => $value) {
  299. switch ($key) {
  300. case 'ToolbarSets':
  301. if (!empty($toolbar_set) && $toolbar_set != 'Default') {
  302. if (is_array($value)) {
  303. if (isset($value['Normal'])) {
  304. if (!isset($this->Config[$key][$toolbar_set])) {
  305. $this->Config[$key][$toolbar_set] = $value['Normal'];
  306. }
  307. }
  308. if (isset($value['Maximized'])) {
  309. if (!isset($this->Config[$key][$toolbar_set_maximized])) {
  310. $this->Config[$key][$toolbar_set_maximized] = $value['Maximized'];
  311. }
  312. }
  313. }
  314. }
  315. break;
  316. case 'Width':
  317. $this->Config[$key] = (string) $value;
  318. $this->Width = $this->Config[$key];
  319. break;
  320. case 'Height':
  321. $this->Config[$key] = (string) $value;
  322. $this->Height = $this->Config[$key];
  323. break;
  324. default:
  325. if (!isset($this->Config[$key])) {
  326. $this->Config[$key] = $value;
  327. }
  328. }
  329. }
  330. }
  331. /**
  332. * This method returns editor's custom configuration settings read from php-files.
  333. * @return array Custom configuration data.
  334. */
  335. private function & get_custom_configuration() {
  336. static $config;
  337. if (!isset($config)) {
  338. require api_get_path(LIBRARY_PATH).'fckeditor/myconfig.php';
  339. }
  340. $toolbar_dir = isset($config['ToolbarSets']['Directory']) ? $config['ToolbarSets']['Directory'] : 'default';
  341. $return = array_merge($config, $this->get_custom_toolbar_configuration($toolbar_dir));
  342. return $return;
  343. }
  344. /**
  345. * This method returns editor's toolbar configuration settings read from a php-file.
  346. * @return array Toolbar configuration data.
  347. */
  348. private function & get_custom_toolbar_configuration($toolbar_dir) {
  349. static $toolbar_config = array('Default' => array());
  350. if (!isset($toolbar_config[$this->ToolbarSet])) {
  351. $toolbar_config[$this->ToolbarSet] = array();
  352. if (preg_match('/[a-zA-Z_]+/', $toolbar_dir) && preg_match('/[a-zA-Z_]+/', $this->ToolbarSet)) { // A security check.
  353. // Seeking the toolbar.
  354. @include api_get_path(LIBRARY_PATH).'fckeditor/toolbars/'.$toolbar_dir.'/'.api_camel_case_to_underscore($this->ToolbarSet).'.php';
  355. if (!isset($config['ToolbarSets']['Normal'])) {
  356. // No toolbar has been found yet.
  357. if ($toolbar_dir == 'default') {
  358. // It does not exist in default toolbar definitions, giving up.
  359. $this->ToolbarSet = 'Default';
  360. } else {
  361. // The custom toolbar does not exist, then trying to load the default one.
  362. @include api_get_path(LIBRARY_PATH).'fckeditor/toolbars/default/'.api_camel_case_to_underscore($this->ToolbarSet).'.php';
  363. if (!isset($config['ToolbarSets']['Normal'])) {
  364. // It does not exist in default toolbar definitions, giving up.
  365. $this->ToolbarSet = 'Default';
  366. } else {
  367. $toolbar_config[$this->ToolbarSet] = $config;
  368. }
  369. }
  370. } else {
  371. $toolbar_config[$this->ToolbarSet] = $config;
  372. }
  373. } else {
  374. $this->ToolbarSet = 'Default';
  375. }
  376. }
  377. return $toolbar_config[$this->ToolbarSet];
  378. }
  379. /**
  380. * This method returns automatically determined editor's configuration settings (default settings).
  381. * @return array
  382. */
  383. private function & get_default_configuration() {
  384. $return_value = array_merge(
  385. self::get_javascript_custom_configuration_file(),
  386. self::get_css_configuration(),
  387. self::get_editor_language(),
  388. $this->get_repository_configuration(),
  389. self::get_media_configuration(),
  390. self::get_user_configuration_data(),
  391. $this->get_mimetex_plugin_configuration()
  392. );
  393. return $return_value;
  394. }
  395. /**
  396. * This method returns the path to the javascript custom configuration file.
  397. * @return array
  398. */
  399. private function & get_javascript_custom_configuration_file() {
  400. $return_value = array('CustomConfigurationsPath' => api_get_path(REL_PATH).'main/inc/lib/fckeditor/myconfig.js');
  401. return $return_value;
  402. }
  403. /**
  404. * This method returns CSS-related configuration data that has been determined by the system.
  405. * @return array
  406. */
  407. private function & get_css_configuration() {
  408. $config['EditorAreaCSS'] = api_get_path(REL_PATH).'main/css/'.api_get_setting('stylesheets').'/default.css';
  409. $config['ToolbarComboPreviewCSS'] = $config['EditorAreaCSS'];
  410. return $config;
  411. }
  412. /**
  413. * This method determines editor's interface language and returns it as compatible with the editor langiage code.
  414. * @return array
  415. */
  416. private function & get_editor_language() {
  417. static $config;
  418. if (!is_array($config)) {
  419. $code_translation_table = array('' => 'en', 'sr' => 'sr-latn', 'zh' => 'zh-cn', 'zh-tw' => 'zh');
  420. $editor_lang = strtolower(str_replace('_', '-', api_get_language_isocode()));
  421. $editor_lang = isset($code_translation_table[$editor_lang]) ? $code_translation_table[$editor_lang] : $editor_lang;
  422. $editor_lang = file_exists(api_get_path(SYS_PATH).'main/inc/lib/fckeditor/editor/lang/'.$editor_lang.'.js') ? $editor_lang : 'en';
  423. $config['DefaultLanguage'] = $editor_lang;
  424. $config['ContentLangDirection'] = api_get_text_direction($editor_lang);
  425. }
  426. return $config;
  427. }
  428. /**
  429. * This method returns default configuration for document repository that is to be used by the editor.
  430. * @return array
  431. */
  432. private function & get_repository_configuration()
  433. {
  434. // Disabling access for anonymous users.
  435. $isAnonymous = api_is_anonymous();
  436. if ($isAnonymous) {
  437. return array();
  438. }
  439. // Preliminary calculations for assembling required paths.
  440. $base_path = $this->BasePath;
  441. $script_name = substr($_SERVER['PHP_SELF'], strlen(api_get_path(REL_PATH)));
  442. $script_path = explode('/', $script_name);
  443. $script_path[count($script_path) - 1] = '';
  444. if (api_is_in_course()) {
  445. $relative_path_prefix = str_repeat('../', count($script_path) - 1);
  446. } else {
  447. $relative_path_prefix = str_repeat('../', count($script_path) - 2);
  448. }
  449. $script_path = implode('/', $script_path);
  450. $script_path = api_get_path(WEB_PATH).$script_path;
  451. $use_advanced_filemanager = api_get_setting('advanced_filemanager') == 'true';
  452. // Let javascripts "know" which file manager has been chosen.
  453. $config['AdvancedFileManager'] = $use_advanced_filemanager;
  454. if (api_is_in_course()) {
  455. if (!api_is_in_group()) {
  456. // 1. We are inside a course and not in a group.
  457. if (api_is_allowed_to_edit()) {
  458. // 1.1. Teacher (tutor and coach are not authorized to change anything in the "content creation" tools)
  459. $config['CreateDocumentWebDir'] = api_get_path(WEB_COURSE_PATH).api_get_course_path().'/document/';
  460. $config['CreateDocumentDir'] = $relative_path_prefix.'courses/'.api_get_course_path().'/document/';
  461. $config['BaseHref'] = $script_path;
  462. } else {
  463. // 1.2. Student
  464. $current_session_id = api_get_session_id();
  465. if($current_session_id==0) {
  466. $config['CreateDocumentWebDir'] = api_get_path(WEB_COURSE_PATH).api_get_course_path().'/document/shared_folder/sf_user_'.api_get_user_id().'/';
  467. $config['CreateDocumentDir'] = $relative_path_prefix.'courses/'.api_get_course_path().'/document/shared_folder/sf_user_'.api_get_user_id().'/';
  468. $config['BaseHref'] = $script_path;
  469. } else {
  470. $config['CreateDocumentWebDir'] = api_get_path(WEB_COURSE_PATH).api_get_course_path().'/document/shared_folder_session_'.$current_session_id.'/sf_user_'.api_get_user_id().'/';
  471. $config['CreateDocumentDir'] = $relative_path_prefix.'courses/'.api_get_course_path().'/document/shared_folder_session_'.$current_session_id.'/sf_user_'.api_get_user_id().'/';
  472. $config['BaseHref'] = $script_path;
  473. }
  474. }
  475. } else {
  476. // 2. Inside a course and inside a group.
  477. global $group_properties;
  478. $config['CreateDocumentWebDir'] = api_get_path(WEB_COURSE_PATH).api_get_course_path().'/document'.$group_properties['directory'].'/';
  479. $config['CreateDocumentDir'] = $relative_path_prefix.'courses/'.api_get_course_path().'/document'.$group_properties['directory'].'/';
  480. $config['BaseHref'] = $script_path;
  481. }
  482. } else {
  483. if (api_is_platform_admin() && isset($_SESSION['this_section']) && $_SESSION['this_section'] == 'platform_admin') {
  484. // 3. Platform administration activities.
  485. $config['CreateDocumentWebDir'] = api_get_path(WEB_PATH).'home/default_platform_document/';
  486. $config['CreateDocumentDir'] = api_get_path(WEB_PATH).'home/default_platform_document/'; // A side-effect is in use here.
  487. $config['BaseHref'] = api_get_path(WEB_PATH).'home/default_platform_document/';
  488. } else {
  489. // 4. The user is outside courses.
  490. $my_path = UserManager::get_user_picture_path_by_id(api_get_user_id(),'system');
  491. $config['CreateDocumentWebDir'] = $my_path['dir'].'my_files/';
  492. $my_path = UserManager::get_user_picture_path_by_id(api_get_user_id(),'rel');
  493. $config['CreateDocumentDir'] = $my_path['dir'].'my_files/';
  494. $config['BaseHref'] = $script_path;
  495. }
  496. }
  497. // URLs for opening the file browser for different resource types (file types):
  498. if ($use_advanced_filemanager) {
  499. // Double slashes within the following URLs for the advanced file manager are put intentionally. Please, keep them.
  500. // for images
  501. $config['ImageBrowserURL'] = $base_path.'/editor/plugins/ajaxfilemanager/ajaxfilemanager.php';
  502. // for flash
  503. $config['FlashBrowserURL'] = $base_path.'/editor/plugins/ajaxfilemanager/ajaxfilemanager.php';
  504. // for audio files (mp3)
  505. $config['MP3BrowserURL'] = $base_path.'/editor/plugins/ajaxfilemanager/ajaxfilemanager.php';
  506. // for video
  507. $config['VideoBrowserURL'] = $base_path.'/editor/plugins/ajaxfilemanager/ajaxfilemanager.php';
  508. // for video (flv)
  509. $config['MediaBrowserURL'] = $base_path.'/editor/plugins/ajaxfilemanager/ajaxfilemanager.php';
  510. // for links (any resource type)
  511. $config['LinkBrowserURL'] = $base_path.'/editor/plugins/ajaxfilemanager/ajaxfilemanager.php';
  512. } else {
  513. // for images
  514. $config['ImageBrowserURL'] = $base_path.'editor/filemanager/browser/default/browser.html?Type=Images&Connector='.$base_path.'editor/filemanager/connectors/php/connector.php';
  515. // for flash
  516. $config['FlashBrowserURL'] = $base_path.'editor/filemanager/browser/default/browser.html?Type=Flash&Connector='.$base_path.'editor/filemanager/connectors/php/connector.php';
  517. // for audio files (mp3)
  518. $config['MP3BrowserURL'] = $base_path.'editor/filemanager/browser/default/browser.html?Type=MP3&Connector='.$base_path.'editor/filemanager/connectors/php/connector.php';
  519. // for video
  520. $config['VideoBrowserURL'] = $base_path.'editor/filemanager/browser/default/browser.html?Type=Video&Connector='.$base_path.'editor/filemanager/connectors/php/connector.php';
  521. // for video (flv)
  522. $config['MediaBrowserURL'] = $base_path.'editor/filemanager/browser/default/browser.html?Type=Video/flv&Connector='.$base_path.'editor/filemanager/connectors/php/connector.php';
  523. // for links (any resource type)
  524. $config['LinkBrowserURL'] = $base_path.'editor/filemanager/browser/default/browser.html?Type=File&Connector='.$base_path.'editor/filemanager/connectors/php/connector.php';
  525. }
  526. // URLs for making quick uplods for different resource types (file types).
  527. // These URLs are used by the dialogs' quick upload tabs:
  528. // for images
  529. $config['ImageUploadURL'] = $base_path.'editor/filemanager/connectors/php/upload.php?Type=Images';
  530. // for flash
  531. $config['FlashUploadURL'] = $base_path.'editor/filemanager/connectors/php/upload.php?Type=Flash';
  532. // for audio files (mp3)
  533. $config['MP3UploadURL'] = $base_path.'editor/filemanager/connectors/php/upload.php?Type=MP3';
  534. // for video
  535. $config['VideoUploadURL'] = $base_path.'editor/filemanager/connectors/php/upload.php?Type=Video';
  536. // for video (flv)
  537. $config['MediaUploadURL'] = $base_path.'editor/filemanager/connectors/php/upload.php?Type=Video/flv';
  538. // for links (any resource type)
  539. $config['LinkUploadURL'] = $base_path.'editor/filemanager/connectors/php/upload.php?Type=File';
  540. return $config;
  541. }
  542. /**
  543. * This method returns multi-media related configuration data.
  544. * @return array
  545. */
  546. private function & get_media_configuration() {
  547. $config['FlashPlayerAudio'] = api_get_path(TO_REL, FLASH_PLAYER_AUDIO);
  548. $config['FlashPlayerVideo'] = api_get_path(TO_REL, FLASH_PLAYER_VIDEO);
  549. $config['ScriptSWFObject'] = api_get_path(TO_REL, SCRIPT_SWFOBJECT);
  550. $config['ScriptASCIIMathML'] = api_get_path(TO_REL, SCRIPT_ASCIIMATHML);
  551. $config['DrawingASCIISVG'] = api_get_path(TO_REL, DRAWING_ASCIISVG);
  552. return $config;
  553. }
  554. /**
  555. * This method returns current user specific configuration data.
  556. * @return array
  557. */
  558. private function & get_user_configuration_data() {
  559. $config['UserIsCourseAdmin'] = api_is_allowed_to_edit() ? true : false;
  560. $config['UserIsPlatformAdmin'] = api_is_platform_admin() ? true : false;
  561. return $config;
  562. }
  563. /**
  564. * This method returns detected configuration data about editor's MimeTeX plugin.
  565. * @return array
  566. */
  567. private function & get_mimetex_plugin_configuration() {
  568. static $config;
  569. if (!isset($config)) {
  570. $config = array();
  571. if (is_array($this->Config['LoadPlugin']) && in_array('mimetex', $this->Config['LoadPlugin'])) {
  572. $server_base = api_get_path(WEB_SERVER_ROOT_PATH);
  573. $server_base_parts = explode('/', $server_base);
  574. $url_relative = 'cgi-bin/mimetex' . ( IS_WINDOWS_OS ? '.exe' : '.cgi' );
  575. if (!isset($this->Config['MimetexExecutableInstalled'])) {
  576. $this->Config['MimetexExecutableDetectionMethod'] = 'detect';
  577. }
  578. if ($this->Config['MimetexExecutableInstalled'] == 'detect') {
  579. $detection_method = isset($this->Config['MimetexExecutableDetectionMethod']) ? $this->Config['MimetexExecutableDetectionMethod'] : 'bootstrap_ip';
  580. $detection_timeout = isset($this->Config['MimetexExecutableDetectionTimeout']) ? $this->Config['MimetexExecutableDetectionTimeout'] : 0.05;
  581. switch ($detection_method) {
  582. case 'bootstrap_ip':
  583. $detection_url = $server_base_parts[0] . '//127.0.0.1/';
  584. break;
  585. case 'localhost':
  586. $detection_url = $server_base_parts[0] . '//localhost/';
  587. break;
  588. case 'ip':
  589. $detection_url = $server_base_parts[0] . '//' . $_SERVER['SERVER_ADDR'] . '/';
  590. break;
  591. default:
  592. $detection_url = $server_base_parts[0] . '//' . $_SERVER['SERVER_NAME'] . '/';
  593. }
  594. $detection_url .= $url_relative . '?' . rand();
  595. $config['IsMimetexInstalled'] = self::url_exists($detection_url, $detection_timeout);
  596. } else {
  597. $config['IsMimetexInstalled'] = $this->Config['MimetexExecutableInstalled'];
  598. }
  599. $config['MimetexUrl'] = api_add_trailing_slash($server_base) . $url_relative;
  600. }
  601. // Cleaning detection related settings, we don't need them anymore.
  602. unset($this->Config['MimetexExecutableInstalled']);
  603. unset($this->Config['MimetexExecutableDetectionMethod']);
  604. unset($this->Config['MimetexExecutableDetectionTimeout']);
  605. }
  606. return $config;
  607. }
  608. /*
  609. * Checks whether a given url exists.
  610. * @param string $url
  611. * @param int $timeout
  612. * @return boolean
  613. * @author Ivan Tcholakov, FEB-2009
  614. */
  615. private function url_exists($url, $timeout = 30) {
  616. $parsed = parse_url($url);
  617. $scheme = isset($parsed['scheme']) ? $parsed['scheme'] : 'http';
  618. $host = $parsed['host'];
  619. $port = isset($parsed['port']) ? $parsed['port'] : ($scheme == 'http' ? 80 : ($scheme == 'https' ? 443 : -1 ));
  620. $file_exists = false;
  621. $fp = @fsockopen($host, $port, $errno, $errstr, $timeout);
  622. if ($fp) {
  623. $request = "HEAD ".$url." / HTTP/1.1\r\n";
  624. $request .= "Host: ".$host."\r\n";
  625. $request .= "Connection: Close\r\n\r\n";
  626. @fwrite($fp, $request);
  627. while (!@feof($fp)) {
  628. $header = @fgets($fp, 128);
  629. if(@preg_match('#HTTP/1.1 200 OK#', $header)) {
  630. $file_exists = true;
  631. break;
  632. }
  633. }
  634. }
  635. @fclose($fp);
  636. return $file_exists;
  637. }
  638. }