Form.class.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Form handling code.
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. /**
  9. * Base class for forms, loads default configuration options, checks allowed
  10. * values etc.
  11. *
  12. * @package PhpMyAdmin
  13. */
  14. class Form
  15. {
  16. /**
  17. * Form name
  18. * @var string
  19. */
  20. public $name;
  21. /**
  22. * Arbitrary index, doesn't affect class' behavior
  23. * @var int
  24. */
  25. public $index;
  26. /**
  27. * Form fields (paths), filled by {@link readFormPaths()}, indexed by field name
  28. * @var array
  29. */
  30. public $fields;
  31. /**
  32. * Stores default values for some fields (eg. pmadb tables)
  33. * @var array
  34. */
  35. public $default;
  36. /**
  37. * Caches field types, indexed by field names
  38. * @var array
  39. */
  40. private $_fieldsTypes;
  41. /**
  42. * ConfigFile instance
  43. * @var ConfigFile
  44. */
  45. private $_configFile;
  46. /**
  47. * Constructor, reads default config values
  48. *
  49. * @param string $form_name Form name
  50. * @param array $form Form data
  51. * @param ConfigFile $cf Config file instance
  52. * @param int $index arbitrary index, stored in Form::$index
  53. */
  54. public function __construct(
  55. $form_name, array $form, ConfigFile $cf, $index = null
  56. ) {
  57. $this->index = $index;
  58. $this->_configFile = $cf;
  59. $this->loadForm($form_name, $form);
  60. }
  61. /**
  62. * Returns type of given option
  63. *
  64. * @param string $option_name path or field name
  65. *
  66. * @return string|null one of: boolean, integer, double, string, select, array
  67. */
  68. public function getOptionType($option_name)
  69. {
  70. $key = ltrim(substr($option_name, strrpos($option_name, '/')), '/');
  71. return isset($this->_fieldsTypes[$key])
  72. ? $this->_fieldsTypes[$key]
  73. : null;
  74. }
  75. /**
  76. * Returns allowed values for select fields
  77. *
  78. * @param string $option_path Option path
  79. *
  80. * @return array
  81. */
  82. public function getOptionValueList($option_path)
  83. {
  84. $value = $this->_configFile->getDbEntry($option_path);
  85. if ($value === null) {
  86. trigger_error("$option_path - select options not defined", E_USER_ERROR);
  87. return array();
  88. }
  89. if (!is_array($value)) {
  90. trigger_error("$option_path - not a static value list", E_USER_ERROR);
  91. return array();
  92. }
  93. // convert array('#', 'a', 'b') to array('a', 'b')
  94. if (isset($value[0]) && $value[0] === '#') {
  95. // remove first element ('#')
  96. array_shift($value);
  97. // $value has keys and value names, return it
  98. return $value;
  99. }
  100. // convert value list array('a', 'b') to array('a' => 'a', 'b' => 'b')
  101. $has_string_keys = false;
  102. $keys = array();
  103. for ($i = 0, $nb = count($value); $i < $nb; $i++) {
  104. if (!isset($value[$i])) {
  105. $has_string_keys = true;
  106. break;
  107. }
  108. $keys[] = is_bool($value[$i]) ? (int)$value[$i] : $value[$i];
  109. }
  110. if (! $has_string_keys) {
  111. $value = array_combine($keys, $value);
  112. }
  113. // $value has keys and value names, return it
  114. return $value;
  115. }
  116. /**
  117. * array_walk callback function, reads path of form fields from
  118. * array (see file comment in setup.forms.php or user_preferences.forms.inc)
  119. *
  120. * @param mixed $value Value
  121. * @param mixed $key Key
  122. * @param mixed $prefix Prefix
  123. *
  124. * @return void
  125. */
  126. private function _readFormPathsCallback($value, $key, $prefix)
  127. {
  128. static $group_counter = 0;
  129. if (is_array($value)) {
  130. $prefix .= $key . '/';
  131. array_walk($value, array($this, '_readFormPathsCallback'), $prefix);
  132. return;
  133. }
  134. if (!is_int($key)) {
  135. $this->default[$prefix . $key] = $value;
  136. $value = $key;
  137. }
  138. // add unique id to group ends
  139. if ($value == ':group:end') {
  140. $value .= ':' . $group_counter++;
  141. }
  142. $this->fields[] = $prefix . $value;
  143. }
  144. /**
  145. * Reads form paths to {@link $fields}
  146. *
  147. * @param array $form Form
  148. *
  149. * @return void
  150. */
  151. protected function readFormPaths($form)
  152. {
  153. // flatten form fields' paths and save them to $fields
  154. $this->fields = array();
  155. array_walk($form, array($this, '_readFormPathsCallback'), '');
  156. // $this->fields is an array of the form: [0..n] => 'field path'
  157. // change numeric indexes to contain field names (last part of the path)
  158. $paths = $this->fields;
  159. $this->fields = array();
  160. foreach ($paths as $path) {
  161. $key = ltrim(substr($path, strrpos($path, '/')), '/');
  162. $this->fields[$key] = $path;
  163. }
  164. // now $this->fields is an array of the form: 'field name' => 'field path'
  165. }
  166. /**
  167. * Reads fields' types to $this->_fieldsTypes
  168. *
  169. * @return void
  170. */
  171. protected function readTypes()
  172. {
  173. $cf = $this->_configFile;
  174. foreach ($this->fields as $name => $path) {
  175. if (strpos($name, ':group:') === 0) {
  176. $this->_fieldsTypes[$name] = 'group';
  177. continue;
  178. }
  179. $v = $cf->getDbEntry($path);
  180. if ($v !== null) {
  181. $type = is_array($v) ? 'select' : $v;
  182. } else {
  183. $type = gettype($cf->getDefault($path));
  184. }
  185. $this->_fieldsTypes[$name] = $type;
  186. }
  187. }
  188. /**
  189. * Reads form settings and prepares class to work with given subset of
  190. * config file
  191. *
  192. * @param string $form_name Form name
  193. * @param array $form Form
  194. *
  195. * @return void
  196. */
  197. public function loadForm($form_name, $form)
  198. {
  199. $this->name = $form_name;
  200. $this->readFormPaths($form);
  201. $this->readTypes();
  202. }
  203. }
  204. ?>