editinstance_form.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. <?php
  2. /**
  3. * Class ChamiloForm
  4. */
  5. abstract class ChamiloForm
  6. {
  7. protected $_form;
  8. protected $_mode;
  9. protected $_cancelurl;
  10. protected $_customdata;
  11. public $_definition_finalized;
  12. /**
  13. * ChamiloForm constructor.
  14. * @param $mode
  15. * @param $returnurl
  16. * @param $cancelurl
  17. * @param $customdata
  18. */
  19. public function __construct($mode, $returnurl, $cancelurl, $customdata = [])
  20. {
  21. global $text_dir;
  22. $this->_mode = $mode;
  23. $this->_cancelurl = $cancelurl;
  24. $this->_customdata = $customdata;
  25. $attributes = array('style' => 'width: 60%; float: '.($text_dir == 'rtl' ? 'right;' : 'left;'));
  26. // $this->_form = new FormValidator($mode.'_instance', 'post', $returnurl, '', $attributes, true);
  27. $this->_form = new FormValidator($mode.'_instance', 'post', $returnurl, '', $attributes);
  28. }
  29. public abstract function definition();
  30. public abstract function validation($data, $files = null);
  31. public function validate()
  32. {
  33. return $this->_form->validate();
  34. }
  35. public function display()
  36. {
  37. return $this->_form->display();
  38. }
  39. public function definition_after_data()
  40. {
  41. }
  42. public function return_form()
  43. {
  44. return $this->_form->toHtml();
  45. }
  46. public function is_in_add_mode()
  47. {
  48. return $this->_mode == 'add';
  49. }
  50. /**
  51. * Return submitted data if properly submitted or returns NULL if validation fails or
  52. * if there is no submitted data.
  53. *
  54. * @param bool $slashed true means return data with addslashes applied
  55. * @return object submitted data; NULL if not valid or not submitted
  56. */
  57. public function get_data($slashed = true)
  58. {
  59. $cform = & $this->_form;
  60. if ($this->is_submitted() and $this->is_validated()) {
  61. $data = $cform->exportValues(null, $slashed);
  62. unset($data['sesskey']); // we do not need to return sesskey
  63. if (empty($data)) {
  64. return null;
  65. } else {
  66. return (object) $data;
  67. }
  68. } else {
  69. return null;
  70. }
  71. }
  72. /**
  73. * Return submitted data without validation or NULL if there is no submitted data.
  74. *
  75. * @param bool $slashed true means return data with addslashes applied
  76. * @return object submitted data; NULL if not submitted
  77. */
  78. public function get_submitted_data($slashed = true)
  79. {
  80. $cform = & $this->_form;
  81. if ($this->is_submitted()) {
  82. $data = $cform->exportValues(null, $slashed);
  83. unset($data['sesskey']); // we do not need to return sesskey
  84. if (empty($data)) {
  85. return null;
  86. } else {
  87. return (object) $data;
  88. }
  89. } else {
  90. return null;
  91. }
  92. }
  93. /**
  94. * Check that form was submitted. Does not check validity of submitted data.
  95. *
  96. * @return bool true if form properly submitted
  97. */
  98. public function is_submitted()
  99. {
  100. return $this->_form->isSubmitted();
  101. }
  102. /**
  103. * Return true if a cancel button has been pressed resulting in the form being submitted.
  104. *
  105. * @return bool true if a cancel button has been pressed
  106. */
  107. public function is_cancelled()
  108. {
  109. $cform = & $this->_form;
  110. if ($cform->isSubmitted()) {
  111. foreach ($cform->_cancelButtons as $cancelbutton) {
  112. if (optional_param($cancelbutton, 0, PARAM_RAW)) {
  113. return true;
  114. }
  115. }
  116. }
  117. return false;
  118. }
  119. /**
  120. * Check that form data is valid.
  121. * You should almost always use this, rather than {@see validate_defined_fields}
  122. *
  123. * @return bool true if form data valid
  124. */
  125. public function is_validated()
  126. {
  127. //finalize the form definition before any processing
  128. if (!$this->_definition_finalized) {
  129. $this->_definition_finalized = true;
  130. $this->definition_after_data();
  131. }
  132. return $this->validate_defined_fields();
  133. }
  134. /**
  135. * Validate the form.
  136. *
  137. * You almost always want to call {@see is_validated} instead of this
  138. * because it calls {@see definition_after_data} first, before validating the form,
  139. * which is what you want in 99% of cases.
  140. *
  141. * This is provided as a separate function for those special cases where
  142. * you want the form validated before definition_after_data is called
  143. * for example, to selectively add new elements depending on a no_submit_button press,
  144. * but only when the form is valid when the no_submit_button is pressed,
  145. *
  146. * @param boolean $validateonnosubmit optional, defaults to false. The default behaviour
  147. * is NOT to validate the form when a no submit button has been pressed.
  148. * pass true here to override this behaviour
  149. *
  150. * @return bool true if form data valid
  151. */
  152. public function validate_defined_fields($validateonnosubmit = false)
  153. {
  154. static $validated = null; // one validation is enough
  155. $cform = & $this->_form;
  156. if ($this->no_submit_button_pressed() && empty($validateonnosubmit)) {
  157. return false;
  158. } elseif ($validated === null) {
  159. $internal_val = $cform->validate();
  160. $files = array();
  161. $file_val = $this->_validate_files($files);
  162. if ($file_val !== true) {
  163. if (!empty($file_val)) {
  164. foreach ($file_val as $element => $msg) {
  165. $cform->setElementError($element, $msg);
  166. }
  167. }
  168. $file_val = false;
  169. }
  170. $data = $cform->exportValues(null, true);
  171. $chamilo_val = $this->validation($data, $files);
  172. if ((is_array($chamilo_val) && count($chamilo_val) !== 0)) {
  173. // non-empty array means errors
  174. foreach ($chamilo_val as $element => $msg) {
  175. $cform->setElementError($element, $msg);
  176. }
  177. $chamilo_val = false;
  178. } else {
  179. // anything else means validation ok
  180. $chamilo_val = true;
  181. }
  182. $validated = ($internal_val and $chamilo_val and $file_val);
  183. }
  184. return $validated;
  185. }
  186. public function no_submit_button_pressed()
  187. {
  188. static $nosubmit = null; // one check is enough
  189. if (!is_null($nosubmit)) {
  190. return $nosubmit;
  191. }
  192. $cform = & $this->_form;
  193. $nosubmit = false;
  194. if (!$this->is_submitted()) {
  195. return false;
  196. }
  197. /*
  198. foreach ($cform->_noSubmitButtons as $nosubmitbutton){
  199. if (optional_param($nosubmitbutton, 0, PARAM_RAW)){
  200. $nosubmit = true;
  201. break;
  202. }
  203. }
  204. return $nosubmit;
  205. */
  206. return false;
  207. }
  208. /**
  209. * Load in existing data as form defaults. Usually new entry defaults are stored directly in
  210. * form definition (new entry form); this function is used to load in data where values
  211. * already exist and data is being edited (edit entry form).
  212. *
  213. * @param mixed $default_values object or array of default values
  214. * @param bool $slashed true if magic quotes applied to data values
  215. */
  216. public function set_data($default_values, $slashed = false)
  217. {
  218. if (is_object($default_values)) {
  219. $default_values = (array) $default_values;
  220. }
  221. $filter = $slashed ? 'stripslashes' : NULL;
  222. $this->_form->setDefaults($default_values, $filter);
  223. }
  224. /**
  225. * Internal method. Validates all uploaded files.
  226. */
  227. public function _validate_files(&$files)
  228. {
  229. $files = array();
  230. if (empty($_FILES)) {
  231. // we do not need to do any checks because no files were submitted
  232. // note: server side rules do not work for files - use custom verification in validate() instead
  233. return true;
  234. }
  235. $errors = array();
  236. $mform = & $this->_form;
  237. // check the files
  238. $status = $this->_upload_manager->preprocess_files();
  239. // now check that we really want each file
  240. foreach ($_FILES as $elname => $file) {
  241. if ($mform->elementExists($elname) and $mform->getElementType($elname) == 'file') {
  242. $required = $mform->isElementRequired($elname);
  243. if (!empty($this->_upload_manager->files[$elname]['uploadlog']) &&
  244. empty($this->_upload_manager->files[$elname]['clear'])
  245. ) {
  246. if (!$required and $file['error'] == UPLOAD_ERR_NO_FILE) {
  247. // file not uploaded and not required - ignore it
  248. continue;
  249. }
  250. $errors[$elname] = $this->_upload_manager->files[$elname]['uploadlog'];
  251. } else if (!empty($this->_upload_manager->files[$elname]['clear'])) {
  252. $files[$elname] = $this->_upload_manager->files[$elname]['tmp_name'];
  253. }
  254. } else {
  255. error('Incorrect upload attempt!');
  256. }
  257. }
  258. // return errors if found
  259. if ($status && 0 == count($errors)) {
  260. return true;
  261. } else {
  262. $files = array();
  263. return $errors;
  264. }
  265. }
  266. }
  267. /**
  268. * Class InstanceForm
  269. */
  270. class InstanceForm extends ChamiloForm
  271. {
  272. /** @var Plugin */
  273. public $_plugin;
  274. public $instance;
  275. /**
  276. * InstanceForm constructor.
  277. * @param $plugin
  278. * @param string $mode
  279. */
  280. public function __construct($plugin, $mode = 'add', $instance = [])
  281. {
  282. global $_configuration;
  283. $this->_plugin = $plugin;
  284. $returnUrl = $_configuration['root_web'].'plugin/vchamilo/views/editinstance.php';
  285. if ($mode == 'update') {
  286. $returnUrl = $_configuration['root_web'].'plugin/vchamilo/views/editinstance.php?vid='.intval($_GET['vid']);
  287. }
  288. $cancelurl = $_configuration['root_web'].'plugin/vchamilo/views/manage.php';
  289. parent::__construct($mode, $returnUrl, $cancelurl);
  290. $this->instance = $instance;
  291. $this->definition();
  292. }
  293. /**
  294. *
  295. */
  296. public function definition()
  297. {
  298. global $_configuration;
  299. $form = $this->_form;
  300. $plugin = $this->_plugin;
  301. $form->addElement('hidden', 'vid');
  302. $form->addElement('hidden', 'what', $this->_mode.'instance');
  303. $form->addElement('hidden', 'registeronly');
  304. $form->addHeader($plugin->get_lang('hostdefinition'));
  305. $form->addText('sitename', [$plugin->get_lang('sitename'), $plugin->get_lang('SiteNameExample')]);
  306. $form->applyFilter('sitename', 'trim');
  307. $form->addText('institution', [$plugin->get_lang('institution'), $plugin->get_lang('InstitutionExample')]);
  308. $form->applyFilter('institution', 'trim');
  309. // Host's name.
  310. $elementWeb = $form->addElement(
  311. 'text',
  312. 'root_web',
  313. [$this->_plugin->get_lang('rootweb'), $plugin->get_lang('RootWebExample')]
  314. );
  315. $form->applyFilter('root_web', 'trim');
  316. $form->addElement(
  317. 'text',
  318. 'url_append',
  319. ['url_append', $plugin->get_lang('UrlAppendExample')]
  320. );
  321. if ($this->_mode == 'update') {
  322. $encryptList = Virtual::getEncryptList();
  323. $encryptMethod = $form->addElement(
  324. 'select',
  325. 'password_encryption',
  326. get_lang('EncryptMethodUserPass'),
  327. $encryptList
  328. );
  329. $encryptMethod->freeze();
  330. $elementWeb->freeze();
  331. }
  332. /*
  333. * Database fieldset.
  334. */
  335. $form->addElement('header', $plugin->get_lang('dbgroup'));
  336. // Database host.
  337. $form->addElement('text', 'db_host', $this->_plugin->get_lang('dbhost'), array('id' => 'id_vdbhost'));
  338. $form->applyFilter('db_host', 'trim');
  339. // Database login.
  340. $form->addElement('text', 'db_user', $this->_plugin->get_lang('dbuser'), array('id' => 'id_vdbuser'));
  341. $form->applyFilter('db_user', 'trim');
  342. // Database password.
  343. $form->addElement(
  344. 'password',
  345. 'db_password',
  346. $this->_plugin->get_lang('dbpassword'),
  347. array('id' => 'id_vdbpassword')
  348. );
  349. // Database name.
  350. $form->addText('main_database', [$plugin->get_lang('maindatabase'), $plugin->get_lang('DatabaseDescription')]);
  351. // Button for testing database connection.
  352. $form->addElement(
  353. 'button',
  354. 'testconnection',
  355. $this->_plugin->get_lang('testconnection'),
  356. 'check',
  357. 'default',
  358. 'default',
  359. '',
  360. 'onclick="opencnxpopup(\''.$_configuration['root_web'].'\'); return false;"'
  361. );
  362. $form->addText('archive_url', $this->_plugin->get_lang('ArchiveUrl'));
  363. $form->addText('home_url', $this->_plugin->get_lang('HomeUrl'));
  364. $form->addText('upload_url', $this->_plugin->get_lang('UploadUrl'));
  365. $form->addText(
  366. 'css_theme_folder',
  367. [
  368. $this->_plugin->get_lang('ThemeFolder'),
  369. $this->_plugin->get_lang('ThemeFolderExplanation'),
  370. ],
  371. false
  372. );
  373. //$form->addText('course_url', $this->_plugin->get_lang('CourseUrl'));
  374. /**
  375. * Template selection.
  376. */
  377. if ($this->is_in_add_mode()) {
  378. $form->addElement('header', $this->_plugin->get_lang('templating'));
  379. $templateoptions = Virtual::getAvailableTemplates();
  380. // Template choice
  381. $form->addSelect(
  382. 'template',
  383. $this->_plugin->get_lang('template'),
  384. $templateoptions
  385. );
  386. } else {
  387. if ($this->instance) {
  388. $form->addLabel(
  389. 'slug',
  390. $this->instance['slug']
  391. );
  392. $form->addLabel(
  393. 'archive_real_root',
  394. api_add_trailing_slash(Virtual::getConfig('vchamilo', 'archive_real_root')).
  395. $this->instance['slug']
  396. );
  397. $form->addLabel(
  398. 'course_real_root',
  399. api_add_trailing_slash(Virtual::getConfig('vchamilo', 'course_real_root')).
  400. $this->instance['slug']
  401. );
  402. $form->addLabel(
  403. 'home_real_root',
  404. api_add_trailing_slash(Virtual::getConfig('vchamilo', 'home_real_root')).$this->instance['slug']
  405. );
  406. $form->addLabel(
  407. 'upload_real_root',
  408. api_add_trailing_slash(Virtual::getConfig('vchamilo', 'upload_real_root')).$this->instance['slug']
  409. );
  410. $form->addLabel(
  411. $this->_plugin->get_lang('template'),
  412. $this->instance['template']
  413. );
  414. }
  415. }
  416. $form->addButtonSave($this->_plugin->get_lang('savechanges'), 'submitbutton');
  417. // Rules
  418. $form->addRule('sitename', $this->_plugin->get_lang('sitenameinputerror'), 'required', null, 'client');
  419. $form->addRule(
  420. 'institution',
  421. $this->_plugin->get_lang('institutioninputerror'),
  422. 'required',
  423. null,
  424. 'client'
  425. );
  426. $form->addRule('root_web', $this->_plugin->get_lang('rootwebinputerror'), 'required', null, 'client');
  427. $form->addRule(
  428. 'main_database',
  429. $this->_plugin->get_lang('databaseinputerror'),
  430. 'required',
  431. null,
  432. 'client'
  433. );
  434. }
  435. /**
  436. * @param array $data
  437. * @param null $files
  438. * @return array
  439. */
  440. public function validation($data, $files = null)
  441. {
  442. global $plugin;
  443. $errors = array();
  444. $tablename = Database::get_main_table('vchamilo');
  445. $vchamilo = Database::select(
  446. '*',
  447. $tablename,
  448. array('where' => array(' root_web = ? ' => array($data['root_web']))),
  449. 'first'
  450. );
  451. if ($vchamilo && isset($data['vid']) && $data['vid'] != $vchamilo['id']) {
  452. $errors['root_web'] = $plugin->get_lang('RootWebExists');
  453. }
  454. if (!empty($errors)) {
  455. return $errors;
  456. }
  457. }
  458. }