PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/symphony/lib/toolkit/fields/field.checkbox.php

https://github.com/bauhouse/sym-designprojectx
PHP | 476 lines | 329 code | 84 blank | 63 comment | 43 complexity | 61d38547f68dfbe13b1d112581b298ac MD5 | raw file
  1. <?php
  2. /**
  3. * @package toolkit
  4. */
  5. /**
  6. * Checkbox field simulates a HTML checkbox field, in that it represents a
  7. * simple yes/no field.
  8. */
  9. class FieldCheckbox extends Field implements ExportableField, ImportableField
  10. {
  11. public function __construct()
  12. {
  13. parent::__construct();
  14. $this->_name = __('Checkbox');
  15. $this->_required = true;
  16. $this->set('required', 'no');
  17. $this->set('location', 'sidebar');
  18. }
  19. /*-------------------------------------------------------------------------
  20. Definition:
  21. -------------------------------------------------------------------------*/
  22. public function canToggle()
  23. {
  24. return true;
  25. }
  26. public function getToggleStates()
  27. {
  28. return array(
  29. 'yes' => __('Yes'),
  30. 'no' => __('No')
  31. );
  32. }
  33. public function toggleFieldData(array $data, $newState, $entry_id = null)
  34. {
  35. $data['value'] = $newState;
  36. return $data;
  37. }
  38. public function canFilter()
  39. {
  40. return true;
  41. }
  42. public function isSortable()
  43. {
  44. return true;
  45. }
  46. public function allowDatasourceOutputGrouping()
  47. {
  48. return true;
  49. }
  50. public function allowDatasourceParamOutput()
  51. {
  52. return true;
  53. }
  54. public function fetchFilterableOperators()
  55. {
  56. return array(
  57. array(
  58. 'title' => 'is',
  59. 'filter' => ' ',
  60. 'help' => __('Find values that are an exact match for the given string.')
  61. )
  62. );
  63. }
  64. public function fetchSuggestionTypes()
  65. {
  66. return array('static');
  67. }
  68. /*-------------------------------------------------------------------------
  69. Setup:
  70. -------------------------------------------------------------------------*/
  71. public function createTable()
  72. {
  73. return Symphony::Database()->query(
  74. "CREATE TABLE IF NOT EXISTS `tbl_entries_data_" . $this->get('id') . "` (
  75. `id` int(11) unsigned NOT null auto_increment,
  76. `entry_id` int(11) unsigned NOT null,
  77. `value` enum('yes','no') NOT null default '".($this->get('default_state') == 'on' ? 'yes' : 'no')."',
  78. PRIMARY KEY (`id`),
  79. UNIQUE KEY `entry_id` (`entry_id`),
  80. KEY `value` (`value`)
  81. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;"
  82. );
  83. }
  84. /*-------------------------------------------------------------------------
  85. Settings:
  86. -------------------------------------------------------------------------*/
  87. public function findDefaults(array &$settings)
  88. {
  89. if (!isset($settings['default_state'])) {
  90. $settings['default_state'] = 'off';
  91. }
  92. }
  93. public function displaySettingsPanel(XMLElement &$wrapper, $errors = null)
  94. {
  95. parent::displaySettingsPanel($wrapper, $errors);
  96. // Checkbox Default State
  97. $label = Widget::Label();
  98. $label->setAttribute('class', 'column');
  99. $input = Widget::Input('fields['.$this->get('sortorder').'][default_state]', 'on', 'checkbox');
  100. if ($this->get('default_state') == 'on') {
  101. $input->setAttribute('checked', 'checked');
  102. }
  103. $label->setValue(__('%s Checked by default', array($input->generate())));
  104. $wrapper->appendChild($label);
  105. // Requirements and table display
  106. $this->appendStatusFooter($wrapper);
  107. }
  108. public function commit()
  109. {
  110. if (!parent::commit()) {
  111. return false;
  112. }
  113. $id = $this->get('id');
  114. if ($id === false) {
  115. return false;
  116. }
  117. $fields = array();
  118. $fields['default_state'] = ($this->get('default_state') ? $this->get('default_state') : 'off');
  119. return FieldManager::saveSettings($id, $fields);
  120. }
  121. /*-------------------------------------------------------------------------
  122. Publish:
  123. -------------------------------------------------------------------------*/
  124. public function displayPublishPanel(XMLElement &$wrapper, $data = null, $flagWithError = null, $fieldnamePrefix = null, $fieldnamePostfix = null, $entry_id = null)
  125. {
  126. if (!$data) {
  127. // TODO: Don't rely on $_POST
  128. if (isset($_POST) && !empty($_POST)) {
  129. $value = 'no';
  130. } elseif ($this->get('default_state') == 'on') {
  131. $value = 'yes';
  132. } else {
  133. $value = 'no';
  134. }
  135. } else {
  136. $value = ($data['value'] === 'yes' ? 'yes' : 'no');
  137. }
  138. $label = Widget::Label();
  139. if ($this->get('required') !== 'yes') {
  140. $label->appendChild(new XMLElement('i', __('Optional')));
  141. }
  142. $input = Widget::Input('fields'.$fieldnamePrefix.'['.$this->get('element_name').']'.$fieldnamePostfix, 'yes', 'checkbox', ($value === 'yes' ? array('checked' => 'checked') : null));
  143. $label->setValue($input->generate(false) . ' ' . $this->get('label'));
  144. if ($flagWithError != null) {
  145. $wrapper->appendChild(Widget::Error($label, $flagWithError));
  146. } else {
  147. $wrapper->appendChild($label);
  148. }
  149. }
  150. public function checkPostFieldData($data, &$message, $entry_id = null)
  151. {
  152. $message = null;
  153. // Check if any value was passed
  154. $has_no_value = is_array($data) ? empty($data) : strlen(trim($data)) == 0;
  155. // Check that the value passed was 'on' or 'yes', if it's not
  156. // then the field has 'no value' in the context of being required. RE: #1569
  157. $has_no_value = ($has_no_value === false) ? !in_array(strtolower($data), array('on', 'yes')) : true;
  158. if ($this->get('required') === 'yes' && $has_no_value) {
  159. $message = __('ā€˜%sā€™ is a required field.', array($this->get('label')));
  160. return self::__MISSING_FIELDS__;
  161. }
  162. return self::__OK__;
  163. }
  164. public function processRawFieldData($data, &$status, &$message = null, $simulate = false, $entry_id = null)
  165. {
  166. $status = self::__OK__;
  167. return array(
  168. 'value' => (strtolower($data) === 'yes' || strtolower($data) == 'on' || $data === true ? 'yes' : 'no')
  169. );
  170. }
  171. /*-------------------------------------------------------------------------
  172. Output:
  173. -------------------------------------------------------------------------*/
  174. public function appendFormattedElement(XMLElement &$wrapper, $data, $encode = false, $mode = null, $entry_id = null)
  175. {
  176. $value = ($data['value'] === 'yes' ? 'Yes' : 'No');
  177. $wrapper->appendChild(new XMLElement($this->get('element_name'), ($encode ? General::sanitize($value) : $value)));
  178. }
  179. public function prepareTextValue($data, $entry_id = null)
  180. {
  181. return $this->prepareExportValue($data, ExportableField::VALUE, $entry_id);
  182. }
  183. public function getParameterPoolValue(array $data, $entry_id = null)
  184. {
  185. return $this->prepareExportValue($data, ExportableField::POSTDATA, $entry_id);
  186. }
  187. /*-------------------------------------------------------------------------
  188. Import:
  189. -------------------------------------------------------------------------*/
  190. public function getImportModes()
  191. {
  192. return array(
  193. 'getValue' => ImportableField::STRING_VALUE,
  194. 'getPostdata' => ImportableField::ARRAY_VALUE
  195. );
  196. }
  197. public function prepareImportValue($data, $mode, $entry_id = null)
  198. {
  199. $status = $message = null;
  200. $modes = (object)$this->getImportModes();
  201. $value = $this->processRawFieldData($data, $status, $message, true, $entry_id);
  202. if ($mode === $modes->getValue) {
  203. return $value['value'];
  204. } elseif ($mode === $modes->getPostdata) {
  205. return $value;
  206. }
  207. return null;
  208. }
  209. /*-------------------------------------------------------------------------
  210. Export:
  211. -------------------------------------------------------------------------*/
  212. /**
  213. * Return a list of supported export modes for use with `prepareExportValue`.
  214. *
  215. * @return array
  216. */
  217. public function getExportModes()
  218. {
  219. return array(
  220. 'getBoolean' => ExportableField::BOOLEAN,
  221. 'getValue' => ExportableField::VALUE,
  222. 'getPostdata' => ExportableField::POSTDATA
  223. );
  224. }
  225. /**
  226. * Give the field some data and ask it to return a value using one of many
  227. * possible modes.
  228. *
  229. * @param mixed $data
  230. * @param integer $mode
  231. * @param integer $entry_id
  232. * @return string|boolean|null
  233. */
  234. public function prepareExportValue($data, $mode, $entry_id = null)
  235. {
  236. $modes = (object)$this->getExportModes();
  237. // Export unformatted:
  238. if ($mode === $modes->getPostdata) {
  239. return (
  240. isset($data['value'])
  241. && $data['value'] === 'yes'
  242. ? 'yes'
  243. : 'no'
  244. );
  245. // Export formatted:
  246. } elseif ($mode === $modes->getValue) {
  247. return (
  248. isset($data['value'])
  249. && $data['value'] === 'yes'
  250. ? __('Yes')
  251. : __('No')
  252. );
  253. // Export boolean:
  254. } elseif ($mode === $modes->getBoolean) {
  255. return (
  256. isset($data['value'])
  257. && $data['value'] === 'yes'
  258. );
  259. }
  260. return null;
  261. }
  262. /*-------------------------------------------------------------------------
  263. Filtering:
  264. -------------------------------------------------------------------------*/
  265. public function displayFilteringOptions(XMLElement &$wrapper)
  266. {
  267. $existing_options = array('yes', 'no');
  268. if (is_array($existing_options) && !empty($existing_options)) {
  269. $optionlist = new XMLElement('ul');
  270. $optionlist->setAttribute('class', 'tags');
  271. $optionlist->setAttribute('data-interactive', 'data-interactive');
  272. foreach ($existing_options as $option) {
  273. $optionlist->appendChild(new XMLElement('li', $option));
  274. }
  275. $wrapper->appendChild($optionlist);
  276. }
  277. }
  278. public function buildDSRetrievalSQL($data, &$joins, &$where, $andOperation = false)
  279. {
  280. $field_id = $this->get('id');
  281. $default_state = ($this->get('default_state') == "on") ? 'yes' : 'no';
  282. if ($andOperation) {
  283. foreach ($data as $value) {
  284. $this->_key++;
  285. $value = $this->cleanValue($value);
  286. $joins .= "
  287. LEFT JOIN
  288. `tbl_entries_data_{$field_id}` AS t{$field_id}_{$this->_key}
  289. ON (e.id = t{$field_id}_{$this->_key}.entry_id)
  290. ";
  291. if ($default_state == $value) {
  292. $where .= "
  293. AND (
  294. t{$field_id}_{$this->_key}.value = '{$value}'
  295. OR
  296. t{$field_id}_{$this->_key}.value IS null
  297. )
  298. ";
  299. } else {
  300. $where .= "
  301. AND (t{$field_id}_{$this->_key}.value = '{$value}')
  302. ";
  303. }
  304. }
  305. } else {
  306. if (!is_array($data)) {
  307. $data = array($data);
  308. }
  309. foreach ($data as &$value) {
  310. $value = $this->cleanValue($value);
  311. }
  312. $this->_key++;
  313. $data = implode("', '", $data);
  314. $joins .= "
  315. LEFT JOIN
  316. `tbl_entries_data_{$field_id}` AS t{$field_id}_{$this->_key}
  317. ON (e.id = t{$field_id}_{$this->_key}.entry_id)
  318. ";
  319. if (strpos($data, $default_state) !== false) {
  320. $where .= "
  321. AND (
  322. t{$field_id}_{$this->_key}.value IN ('{$data}')
  323. OR
  324. t{$field_id}_{$this->_key}.value IS null
  325. )
  326. ";
  327. } else {
  328. $where .= "
  329. AND (t{$field_id}_{$this->_key}.value IN ('{$data}'))
  330. ";
  331. }
  332. }
  333. return true;
  334. }
  335. /*-------------------------------------------------------------------------
  336. Sorting:
  337. -------------------------------------------------------------------------*/
  338. public function buildSortingSQL(&$joins, &$where, &$sort, $order = 'ASC')
  339. {
  340. if ($this->isRandomOrder($order)) {
  341. $sort = 'ORDER BY RAND()';
  342. } else {
  343. $sort = sprintf(
  344. 'ORDER BY (
  345. SELECT %s
  346. FROM tbl_entries_data_%d AS `ed`
  347. WHERE entry_id = e.id
  348. ) %s, `e`.`id` %s',
  349. '`ed`.value',
  350. $this->get('id'),
  351. $order,
  352. $order
  353. );
  354. }
  355. }
  356. public function buildSortingSelectSQL($sort, $order = 'ASC')
  357. {
  358. return null;
  359. }
  360. /*-------------------------------------------------------------------------
  361. Grouping:
  362. -------------------------------------------------------------------------*/
  363. public function groupRecords($records)
  364. {
  365. if (!is_array($records) || empty($records)) {
  366. return;
  367. }
  368. $groups = array($this->get('element_name') => array());
  369. foreach ($records as $r) {
  370. $data = $r->getData($this->get('id'));
  371. $value = $data['value'];
  372. if (!isset($groups[$this->get('element_name')][$value])) {
  373. $groups[$this->get('element_name')][$value] = array(
  374. 'attr' => array('value' => $value),
  375. 'records' => array(),
  376. 'groups' => array()
  377. );
  378. }
  379. $groups[$this->get('element_name')][$value]['records'][] = $r;
  380. }
  381. return $groups;
  382. }
  383. /*-------------------------------------------------------------------------
  384. Events:
  385. -------------------------------------------------------------------------*/
  386. public function getExampleFormMarkup()
  387. {
  388. $label = Widget::Label($this->get('label'));
  389. $label->appendChild(Widget::Input('fields['.$this->get('element_name').']', 'yes', 'checkbox', ($this->get('default_state') == 'on' ? array('checked' => 'checked') : null)));
  390. return $label;
  391. }
  392. }