PageRenderTime 96ms CodeModel.GetById 41ms RepoModel.GetById 10ms app.codeStats 0ms

/inc/bx/dbforms2/config.php

https://github.com/chregu/fluxcms
PHP | 604 lines | 320 code | 96 blank | 188 comment | 61 complexity | a4466cbf9a02d703eeaf5ac04ef3bdf9 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, Apache-2.0, LGPL-2.1
  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | Flux CMS |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 2001-2007 Liip AG |
  6. // +----------------------------------------------------------------------+
  7. // | This program is free software; you can redistribute it and/or |
  8. // | modify it under the terms of the GNU General Public License (GPL) |
  9. // | as published by the Free Software Foundation; either version 2 |
  10. // | of the License, or (at your option) any later version. |
  11. // | The GPL can be found at http://www.gnu.org/licenses/gpl.html |
  12. // +----------------------------------------------------------------------+
  13. // | Author: Liip AG <contact@liip.ch> |
  14. // +----------------------------------------------------------------------+
  15. //
  16. // $Id$
  17. /**
  18. * DOCUMENT_ME
  19. *
  20. * @package bx_dbforms2
  21. * @category
  22. * @author Liip AG <contact@liip.ch>
  23. */
  24. class bx_dbforms2_config {
  25. /**
  26. * Config file as a DOM-object
  27. * @var dom
  28. */
  29. protected $dom = NULL;
  30. /**
  31. * XPath-object to query the config file
  32. * @var xpath
  33. */
  34. protected $xpath = NULL;
  35. /**
  36. * Name of the currently loaded form
  37. * @var name
  38. */
  39. protected $name = '';
  40. /**
  41. * constructor
  42. *
  43. * @param string $name Name of the form
  44. * @access public
  45. */
  46. public function __construct($name = NULL) {
  47. $this->dom = new DOMDocument();
  48. if(isset($name)) {
  49. $this->load($name);
  50. }
  51. $this->dom->xinclude();
  52. }
  53. /**
  54. * Loads a form configuration by its name. The default location for
  55. * form configuration files is BX_PROJECT_DIR/dbforms2/formname.xml
  56. *
  57. * @param string $name Name of the form
  58. * @access public
  59. * @return boolean TRUE on success, FALSE otherwise
  60. *
  61. */
  62. public function load($name) {
  63. $this->name = $name;
  64. $file = $this->getConfigFileByName($name);
  65. return $this->loadFromFile($file);
  66. }
  67. /**
  68. * Loads a form configuration from a file.
  69. *
  70. * @param string $file Name of the configuration file
  71. * @access public
  72. * @return boolean TRUE on success, FALSE otherwise
  73. */
  74. protected function loadFromFile($file) {
  75. if(!file_exists($file)) {
  76. throw new PopoonFileNotFoundException($file);
  77. }
  78. if(@$this->dom->load($file)) {
  79. $this->xpath = new DOMXPath($this->dom);
  80. // register dbforms2 namespace
  81. $this->xpath->registerNamespace('dbform', 'http://www.flux-cms.org/dbforms2/1.0');
  82. return TRUE;
  83. } else {
  84. throw new PopoonXMLParseErrorException($file);
  85. }
  86. return FALSE;
  87. }
  88. /**
  89. * Returns the name of the configuration file which corresponds to
  90. * a form name.
  91. *
  92. * @param string $name Name of the form
  93. * @access public
  94. * @return string Configuration file name
  95. */
  96. public function getConfigFileByName($name) {
  97. return BX_PROJECT_DIR."dbforms2/$name.xml";
  98. }
  99. /**
  100. * Returns an array containing all fields of the current form.
  101. *
  102. * @param DOMElement $fieldsNode The <fields/> node of the form.
  103. * @param object $parentForm The form's parent form.
  104. * @access public
  105. * @return array All fields of the form, including child forms.
  106. */
  107. public function getFields($fieldsNode, $parentForm) {
  108. $fields = array();
  109. // get nodeset which contains all fields of the current form
  110. $fieldsNS = $this->xpath->query('dbform:field|dbform:group|dbform:nofield|dbform:form', $fieldsNode);
  111. foreach($fieldsNS as $field) {
  112. switch($field->localName) {
  113. case 'form';
  114. $name = $field->getAttribute('name');
  115. $form = $this->getForm($field);
  116. $fields[$name] = $form;
  117. break;
  118. // field, nofield and group are subclasses of bx_dbforms2_field
  119. case 'field':
  120. case 'group':
  121. case 'nofield':
  122. $type = $field->getAttribute('type');
  123. $name = $field->getAttribute('name');
  124. if($field->localName == 'field') {
  125. $fieldInstance = $this->getFieldInstance($type, $name);
  126. } else if($field->localName == 'group') {
  127. $fieldInstance = $this->getGroupInstance($type, $name);
  128. } else if($field->localName == 'nofield') {
  129. $fieldInstance = $this->getNofieldInstance($type, $name);
  130. }
  131. if($fieldInstance instanceof bx_dbforms2_field) {
  132. $fieldInstance->parentForm = $parentForm;
  133. $attributeSet = $fieldInstance->getConfigAttributes();
  134. $attributes = $this->getNodeAttributes($field, $attributeSet);
  135. $fieldInstance->setAttributes($attributes);
  136. // check if this field has values from the config file
  137. if($fieldInstance->hasConfigValues()) {
  138. $fieldInstance->setValues($this->getFieldValues($field));
  139. }
  140. if(($default = $this->getDefaultFieldValue($field)) !== NULL) {
  141. $fieldInstance->setDefaultValue($default);
  142. }
  143. if($field->localName == 'field') {
  144. // check if this field has a live select
  145. $lsNS = $this->xpath->query('dbform:liveselect', $field);
  146. if($lsNS->length > 0) {
  147. $lsNode = $lsNS->item(0);
  148. $type = $lsNode->getAttribute("type");
  149. if ($type == 'pagetree') {
  150. $liveSelect = new bx_dbforms2_liveselect_pagetree();
  151. $liveSelect->subtree = $lsNode->getAttribute('subtree');
  152. } else if ($type == 'uid') {
  153. $liveSelect = new bx_dbforms2_liveselect_uid();
  154. $liveSelect->subtree = $lsNode->getAttribute('subtree');
  155. } else {
  156. $liveSelect = new bx_dbforms2_liveselect();
  157. $liveSelect->nameField = $lsNode->getAttribute('namefield');
  158. $liveSelect->whereFields = $lsNode->getAttribute('wherefields');
  159. $liveSelect->where = $lsNode->getAttribute('where');
  160. $liveSelect->idField = $lsNode->getAttribute('idfield');
  161. $liveSelect->tableName = $lsNode->getAttribute('table');
  162. $liveSelect->orderBy = $lsNode->getAttribute('orderby');
  163. $liveSelect->limit = $lsNode->getAttribute('limit');
  164. $liveSelect->setLeftJoin($lsNode->getAttribute('leftjoin'));
  165. }
  166. if(!$liveSelect->limit) {
  167. $liveSelect->limit = 20;
  168. }
  169. $liveSelect->getMatcher = $lsNode->getAttribute('getmatcher');
  170. $fieldInstance->liveSelect = $liveSelect;
  171. }
  172. } else if($field->localName == 'group') {
  173. $fieldInstance->setFields($this->getFields($field, $parentForm));
  174. } else if($field->localName == 'nofield') {
  175. $fieldInstance->setValue($field->getAttribute('value'));
  176. }
  177. $fields[$name] = $fieldInstance;
  178. } else if($fieldInstance instanceof bx_dbforms2_form) {
  179. $fields[$name] = $fieldInstance;
  180. } else {
  181. throw new Exception("Cannot instanciate $name ($type)");
  182. }
  183. default:
  184. break;
  185. }
  186. }
  187. return $fields;
  188. }
  189. /**
  190. * Returns all values for the given field as an array.
  191. *
  192. * @param DOMNode $fieldNode Node of the field
  193. * @access protected
  194. * @return array Field values
  195. */
  196. protected function getFieldValues($fieldNode) {
  197. $values = array();
  198. $valuesNS = $this->xpath->query('dbform:datasource', $fieldNode);
  199. foreach ($valuesNS as $valueNode) {
  200. $type = $valueNode->getAttribute("type");
  201. $className = 'bx_dbforms2_datasource_'.$type;
  202. $ds = call_user_func(array( $className, 'getInstance'));
  203. $args = array();
  204. foreach ($valueNode->attributes as $attr) {
  205. $args[$attr->name] = $attr->value;
  206. }
  207. if ($valueNode->firstChild) {
  208. $childValue = $valueNode->firstChild->nodeValue;
  209. } else {
  210. $childValue = null;
  211. }
  212. $values = $ds->getValues($args,$childValue);
  213. }
  214. $valuesNS = $this->xpath->query('dbform:value', $fieldNode);
  215. foreach ($valuesNS as $valueNode) {
  216. $values[$valueNode->getAttribute('name')] = $valueNode->textContent;
  217. }
  218. return $values;
  219. }
  220. /**
  221. * Returns the default value for the given field.
  222. *
  223. * @param DOMNode $fieldNode Node of the field
  224. * @access protected
  225. * @return string Default field value
  226. */
  227. protected function getDefaultFieldValue($fieldNode) {
  228. $fieldName = $fieldNode->getAttribute('name');
  229. if($fieldNode->hasAttribute('default')) {
  230. return $this->replaceByRequestVar($fieldName, $fieldNode->getAttribute('default'));
  231. }
  232. $valueNS = $fieldNode->getElementsByTagName('value');
  233. if($valueNS->length > 0)
  234. return $this->replaceByRequestVar($fieldName, $valueNS->item(0)->textContent);
  235. return $this->replaceByRequestVar($fieldName, '');
  236. }
  237. /**
  238. * Replaces the given value by the request variable referenced in fieldName. If
  239. * the request variable is NULL, the passed value will be returned.
  240. *
  241. * @param string $name Name of the request variable.
  242. * @param string $value Value to be replaced.
  243. * @access protected
  244. * @return string Value of the request variable or the passed value
  245. */
  246. protected function replaceByRequestVar($name, $value) {
  247. if(isset($_REQUEST[$name])) {
  248. return $_REQUEST[$name];
  249. }
  250. if ($value == '${userid}') {
  251. return bx_helpers_perm::getUserId();
  252. }
  253. return $value;
  254. }
  255. /**
  256. * Returns a form instance for the given form node.
  257. *
  258. * @access public
  259. * @return object Form object
  260. */
  261. public function getForm($formNode) {
  262. $fieldsNS = $this->xpath->query("dbform:fields", $formNode);
  263. $fieldsNode = $fieldsNS->item(0);
  264. $form = new bx_dbforms2_form();
  265. $form->fields = $this->getFields($fieldsNode, $form);
  266. $form->chooser = $this->getChooser($formNode);
  267. $formName = $formNode->getAttribute('name');
  268. if(!empty($formName)) {
  269. $form->name = $formName;
  270. } else {
  271. $form->name = $this->name;
  272. }
  273. $form->tableName = $this->getTableName($formNode);
  274. $form->tablePrefix = $this->getTablePrefix($formNode);
  275. $form->title = $this->getFormTitle($fieldsNode);
  276. $form->eventHandlers = $this->getEventHandlersByForm($fieldsNode->parentNode);
  277. $attributeSet = $form->getConfigAttributes();
  278. $attributes = $this->getNodeAttributes($fieldsNode, $attributeSet);
  279. // backward compatibility for the onsavephp attribute
  280. if(!empty($attributes['onsavephp'])) {
  281. $form->eventHandlers['php'][bx_dbforms2::EVENT_UPDATE_POST][] = $attributes['onsavephp'];
  282. unset($attributes['onsavephp']);
  283. }
  284. $form->attributes = $attributes;
  285. if(!empty($form->attributes['thatidfield'])) {
  286. $fieldInstance = $this->getFieldInstance('hidden', $form->attributes['thatidfield']);
  287. $fieldInstance->parentForm = $form;
  288. $form->fields[] = $fieldInstance;
  289. }
  290. $form->jsHrefs = $this->getJSHrefs();
  291. return $form;
  292. }
  293. /**
  294. * Returns the main form instance.
  295. *
  296. * @access public
  297. * @return object Form object
  298. */
  299. public function getMainForm() {
  300. $formNS = $this->xpath->query("/dbform:form");
  301. return $this->getForm($formNS->item(0));
  302. }
  303. /**
  304. * Returns the chooser object for the given form node.
  305. *
  306. * @param object $formNode The form node for which to get the chooser.
  307. * @access public
  308. * @return object The chooser object of the given form.
  309. */
  310. public function getChooser($formNode) {
  311. $chooserNS = $this->xpath->query("dbform:chooser", $formNode);
  312. $chooserNode = $chooserNS->item(0);
  313. if(!isset($chooserNode)) {
  314. return FALSE;
  315. }
  316. $chooser = new bx_dbforms2_liveselect();
  317. $chooser->nameField = $chooserNode->getAttribute('namefield');
  318. $chooser->whereFields = $chooserNode->getAttribute('wherefields');
  319. $chooser->where = $chooserNode->getAttribute('where');
  320. $chooser->limit = $chooserNode->getAttribute('limit');
  321. if(!$chooser->limit)
  322. $chooser->limit = 20;
  323. $chooser->orderBy = $chooserNode->getAttribute('orderby');
  324. $chooser->getMatcher = $chooserNode->getAttribute('getmatcher');
  325. $chooser->notNullFields = $chooserNode->getAttribute('notnullfields');
  326. $chooser->tableName = $this->getTableName($formNode);
  327. $chooser->tablePrefix = $this->getTablePrefix($formNode);
  328. $chooser->setLeftJoin($chooserNode->getAttribute('leftjoin'));
  329. return $chooser;
  330. }
  331. /**
  332. * Returns the title of a form.
  333. *
  334. * @param DOMElement $fieldsNode The <fields/> node of the form.
  335. * @access protected
  336. * @return string The form's title
  337. */
  338. protected function getFormTitle($fieldsNode = NULL) {
  339. if(!isset($fieldsNode)) {
  340. $fieldsNS = $this->xpath->query("/dbform:form/dbform:fields");
  341. $fieldsNode = $fieldsNS->item(0);
  342. }
  343. if($fieldsNode && $fieldsNode->parentNode->hasAttribute('title'))
  344. return $fieldsNode->parentNode->getAttribute('title');
  345. return '';
  346. }
  347. /**
  348. * Returns the table name of a form.
  349. *
  350. * @param DOMElement $fieldsNode The <fields/> node of the form.
  351. * @access protected
  352. * @return string The form's table name
  353. */
  354. protected function getTableName($formNode = NULL) {
  355. $fieldsNS = $this->xpath->query("dbform:fields", $formNode);
  356. $fieldsNode = $fieldsNS->item(0);
  357. if($fieldsNode && $fieldsNode->hasAttribute('table')) {
  358. return $fieldsNode->getAttribute('table');
  359. }
  360. return FALSE;
  361. }
  362. /**
  363. * Returns the table prefix of a form.
  364. *
  365. * @param DOMElement $fieldsNode The <fields/> node of the form.
  366. * @access protected
  367. * @return string The form's table prefix
  368. */
  369. protected function getTablePrefix($formNode = NULL) {
  370. $fieldsNS = $this->xpath->query("dbform:fields", $formNode);
  371. $fieldsNode = $fieldsNS->item(0);
  372. if($fieldsNode && $fieldsNode->hasAttribute('tablePrefix')) {
  373. return $fieldsNode->getAttribute('tablePrefix');
  374. }
  375. return $GLOBALS['POOL']->config->getTablePrefix();
  376. }
  377. /**
  378. * Returns an instance of the given field type.
  379. *
  380. * @param string $field Type of the field
  381. * @param string $name Name of the field
  382. * @access protected
  383. * @return object Field instance on succes, FALSE otherwise
  384. */
  385. protected function getFieldInstance($field, $name) {
  386. $class = "bx_dbforms2_fields_$field";
  387. return new $class($name);
  388. }
  389. /**
  390. * Returns an instance of the given group type.
  391. *
  392. * @param string $field Type of the field
  393. * @param string $name Name of the field
  394. * @access protected
  395. * @return object Field instance on succes, FALSE otherwise
  396. */
  397. protected function getGroupInstance($field, $name) {
  398. $class = "bx_dbforms2_groups_$field";
  399. return new $class($name);
  400. }
  401. /**
  402. * Returns an instance of the given nofield type.
  403. *
  404. * @param string $field Type of the element
  405. * @param string $name Name of the element
  406. * @access protected
  407. * @return object Field instance on succes, FALSE otherwise
  408. */
  409. protected function getNofieldInstance($field, $name) {
  410. $class = "bx_dbforms2_nofield_$field";
  411. return new $class($name);
  412. }
  413. /**
  414. * Returns an array with all attributes for the given field node and
  415. * attribute set.
  416. *
  417. * @param DOMElement $node DOM-node of the field
  418. * @param array $attributeSet Attribute set
  419. * @access protected
  420. * @return array Array containing all field attributes
  421. */
  422. protected function getNodeAttributes($node, $attributeSet = NULL) {
  423. $attributes = array();
  424. foreach($attributeSet as $attribute => $type) {
  425. $attributes[$attribute] = NULL;
  426. if($node->hasAttribute($attribute)) {
  427. $value = $node->getAttribute($attribute);
  428. if($type === 'bool' || $type === 'boolean') {
  429. $value = strtolower($value) === 'true' ? TRUE : FALSE;
  430. }
  431. $attributes[$attribute] = $value;
  432. }
  433. }
  434. return $attributes;
  435. }
  436. /**
  437. * Returns an array containing all javascript hrefs defined for a form.
  438. *
  439. * @access public
  440. * @return array Array with hrefs
  441. */
  442. protected function getJSHrefs() {
  443. $hrefs = array();
  444. $jsNS = $this->xpath->query("/dbform:form/dbform:javascript");
  445. foreach($jsNS as $jsNode) {
  446. if($jsNode->hasAttribute('src')) {
  447. $hrefs[] = $jsNode->getAttribute('src');
  448. }
  449. }
  450. return $hrefs;
  451. }
  452. /**
  453. * Returns all events handlers of the given type
  454. *
  455. * @param DOMElement $node DOM-node of the form
  456. * @access public
  457. * @return array Array with event all handlers
  458. */
  459. protected function getEventHandlersByForm($node) {
  460. $ehandlers = array();
  461. // <dbform:eventhandler event="insert_pre" type="php" handler="foo::bar"/>
  462. $ehNS = $this->xpath->query("dbform:eventhandler", $node);
  463. foreach($ehNS as $ehNode) {
  464. $type = $ehNode->getAttribute('type');
  465. $event = $ehNode->getAttribute('event');
  466. $handler = $ehNode->getAttribute('handler');
  467. if(!empty($handler) && !empty($event)) {
  468. if(!isset($ehandlers[$type])) {
  469. $ehandlers[$type] = array();
  470. }
  471. switch($event) {
  472. case 'select_pre':
  473. $ehandlers[$type][bx_dbforms2::EVENT_SELECT_PRE][] = $handler;
  474. break;
  475. case 'select_post':
  476. $ehandlers[$type][bx_dbforms2::EVENT_SELECT_POST][] = $handler;
  477. break;
  478. case 'insert_pre':
  479. $ehandlers[$type][bx_dbforms2::EVENT_INSERT_PRE][] = $handler;
  480. break;
  481. case 'insert_post':
  482. $ehandlers[$type][bx_dbforms2::EVENT_INSERT_POST][] = $handler;
  483. break;
  484. case 'update_pre':
  485. $ehandlers[$type][bx_dbforms2::EVENT_UPDATE_PRE][] = $handler;
  486. break;
  487. case 'update_post':
  488. $ehandlers[$type][bx_dbforms2::EVENT_UPDATE_POST][] = $handler;
  489. break;
  490. case 'delete_pre':
  491. $ehandlers[$type][bx_dbforms2::EVENT_DELETE_PRE][] = $handler;
  492. break;
  493. case 'delete_post':
  494. $ehandlers[$type][bx_dbforms2::EVENT_DELETE_POST][] = $handler;
  495. break;
  496. case 'copy_pre':
  497. $ehandlers[$type][bx_dbforms2::EVENT_COPY_PRE][] = $handler;
  498. break;
  499. case 'copy_post':
  500. $ehandlers[$type][bx_dbforms2::EVENT_COPY_POST][] = $handler;
  501. break;
  502. }
  503. }
  504. }
  505. return $ehandlers;
  506. }
  507. }
  508. ?>