editinstance_form.php 15 KB

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