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