fckeditor.php 24 KB

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