editinstance_form.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  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. public $_plugin;
  272. public $instance;
  273. /**
  274. * InstanceForm constructor.
  275. * @param $plugin
  276. * @param string $mode
  277. */
  278. public function __construct($plugin, $mode = 'add', $instance = [])
  279. {
  280. global $_configuration;
  281. $this->_plugin = $plugin;
  282. $returnurl = $_configuration['root_web'].'plugin/vchamilo/views/editinstance.php';
  283. if ($mode == 'update') {
  284. $returnurl = $_configuration['root_web'].'plugin/vchamilo/views/editinstance.php?vid='.intval($_GET['vid']);
  285. }
  286. $cancelurl = $_configuration['root_web'].'plugin/vchamilo/views/manage.php';
  287. parent::__construct($mode, $returnurl, $cancelurl);
  288. $this->instance = $instance;
  289. $this->definition();
  290. }
  291. /**
  292. *
  293. */
  294. public function definition()
  295. {
  296. global $_configuration;
  297. $cform = $this->_form;
  298. /*
  299. * Host's id.
  300. */
  301. $cform->addElement('hidden', 'vid');
  302. $cform->addElement('hidden', 'what', $this->_mode.'instance');
  303. $cform->addElement('hidden', 'registeronly');
  304. /*
  305. * Features fieldset.
  306. */
  307. $cform->addElement('header', $this->_plugin->get_lang('hostdefinition'));
  308. // Name.
  309. $cform->addElement('text', 'sitename', $this->_plugin->get_lang('sitename'));
  310. $cform->applyFilter('sitename', 'trim');
  311. $cform->addElement(
  312. 'text',
  313. 'institution',
  314. $this->_plugin->get_lang('institution')
  315. );
  316. $cform->applyFilter('institution', 'trim');
  317. // Host's name.
  318. $elementWeb = $cform->addElement(
  319. 'text',
  320. 'root_web',
  321. $this->_plugin->get_lang('rootweb')
  322. );
  323. $cform->applyFilter('root_web', 'trim');
  324. if ($this->_mode == 'update') {
  325. $elementWeb->freeze();
  326. }
  327. /*
  328. * Database fieldset.
  329. */
  330. $cform->addElement('header', $this->_plugin->get_lang('dbgroup'));
  331. // Database host.
  332. $cform->addElement('text', 'db_host', $this->_plugin->get_lang('dbhost'), array('id' => 'id_vdbhost'));
  333. $cform->applyFilter('db_host', 'trim');
  334. // Database login.
  335. $cform->addElement('text', 'db_user', $this->_plugin->get_lang('dbuser'), array('id' => 'id_vdbuser'));
  336. $cform->applyFilter('db_user', 'trim');
  337. // Database password.
  338. $cform->addElement(
  339. 'password',
  340. 'db_password',
  341. $this->_plugin->get_lang('dbpassword'),
  342. array('id' => 'id_vdbpassword')
  343. );
  344. // Database name.
  345. $cform->addElement('text', 'main_database', $this->_plugin->get_lang('maindatabase'));
  346. // Button for testing database connection.
  347. $cform->addElement(
  348. 'button',
  349. 'testconnection',
  350. $this->_plugin->get_lang('testconnection'),
  351. 'check',
  352. 'default',
  353. 'default',
  354. '',
  355. 'onclick="opencnxpopup(\''.$_configuration['root_web'].'\'); return false;"'
  356. );
  357. /*
  358. * Template selection.
  359. */
  360. if ($this->is_in_add_mode()) {
  361. $cform->addElement('header', $this->_plugin->get_lang('templating'));
  362. $templateoptions = vchamilo_get_available_templates();
  363. // Template choice
  364. $cform->addElement('select', 'template', $this->_plugin->get_lang('template'), $templateoptions);
  365. } else {
  366. if ($this->instance) {
  367. $cform->addLabel($this->_plugin->get_lang('template'), $this->instance->template);
  368. }
  369. }
  370. $cform->addButtonSave($this->_plugin->get_lang('savechanges'), 'submitbutton');
  371. // Rules
  372. $cform->addRule('sitename', $this->_plugin->get_lang('sitenameinputerror'), 'required', null, 'client');
  373. $cform->addRule(
  374. 'institution',
  375. $this->_plugin->get_lang('institutioninputerror'),
  376. 'required',
  377. null,
  378. 'client'
  379. );
  380. $cform->addRule('root_web', $this->_plugin->get_lang('rootwebinputerror'), 'required', null, 'client');
  381. $cform->addRule(
  382. 'main_database',
  383. $this->_plugin->get_lang('databaseinputerror'),
  384. 'required',
  385. null,
  386. 'client'
  387. );
  388. }
  389. /**
  390. * @param array $data
  391. * @param null $files
  392. * @return array
  393. */
  394. public function validation($data, $files = null)
  395. {
  396. global $plugininstance;
  397. $errors = array();
  398. $tablename = Database::get_main_table('vchamilo');
  399. $vchamilo = Database::select(
  400. '*',
  401. $tablename,
  402. array('where' => array(' root_web = ? ' => array($data['root_web']))),
  403. 'first'
  404. );
  405. if ($vchamilo && isset($data['vid']) && $data['vid'] != $vchamilo['id']) {
  406. $errors['root_web'] = $plugininstance->get_lang('errorrootwebexists');
  407. }
  408. if (!empty($errors)) {
  409. return $errors;
  410. }
  411. }
  412. }