1. sfModelGeneratorConfiguration.class.php
  2. /** * Model generator configuration. * * @package symfony * @subpackage generator * @author Fabien Potencier * @version SVN: $Id: sfModelGeneratorConfiguration.class.php 23898 2009-11-14 13:14:04Z bschussek $ */
  3. abstract class sfModelGeneratorConfiguration
  4. {
  5. protected
  6. $configuration = array();
  7. abstract public function getActionsDefault();
  8. abstract public function getFormActions();
  9. abstract public function getNewActions();
  10. abstract public function getEditActions();
  11. abstract public function getListObjectActions();
  12. abstract public function getListActions();
  13. abstract public function getListBatchActions();
  14. abstract public function getListParams();
  15. abstract public function getListLayout();
  16. abstract public function getListTitle();
  17. abstract public function getEditTitle();
  18. abstract public function getNewTitle();
  19. abstract public function getFilterDisplay();
  20. abstract public function getFormDisplay();
  21. abstract public function getNewDisplay();
  22. abstract public function getEditDisplay();
  23. abstract public function getListDisplay();
  24. abstract public function getFieldsDefault();
  25. abstract public function getFieldsList();
  26. abstract public function getFieldsFilter();
  27. abstract public function getFieldsForm();
  28. abstract public function getFieldsEdit();
  29. abstract public function getFieldsNew();
  30. abstract public function getFormClass();
  31. abstract public function hasFilterForm();
  32. abstract public function getFilterFormClass();
  33. /**
  34. * Constructor.
  35. */
  36. public function __construct()
  37. {
  38. $this->compile();
  39. }
  40. protected function compile()
  41. {
  42. $config = $this->getConfig();
  43. // inheritance rules:
  44. // new|edit < form < default
  45. // list < default
  46. // filter < default
  47. $this->configuration = array(
  48. 'list' => array(
  49. 'fields' => array(),
  50. 'layout' => $this->getListLayout(),
  51. 'title' => $this->getListTitle(),
  52. 'actions' => $this->getListActions(),
  53. 'object_actions' => $this->getListObjectActions(),
  54. 'params' => $this->getListParams(),
  55. ),
  56. 'filter' => array(
  57. 'fields' => array(),
  58. ),
  59. 'form' => array(
  60. 'fields' => array(),
  61. ),
  62. 'new' => array(
  63. 'fields' => array(),
  64. 'title' => $this->getNewTitle(),
  65. 'actions' => $this->getNewActions() ? $this->getNewActions() : $this->getFormActions(),
  66. ),
  67. 'edit' => array(
  68. 'fields' => array(),
  69. 'title' => $this->getEditTitle(),
  70. 'actions' => $this->getEditActions() ? $this->getEditActions() : $this->getFormActions(),
  71. ),
  72. );
  73. foreach (array_keys($config['default']) as $field)
  74. {
  75. $formConfig = array_merge($config['default'][$field], isset($config['form'][$field]) ? $config['form'][$field] : array());
  76. $this->configuration['list']['fields'][$field] = new sfModelGeneratorConfigurationField($field, array_merge(array('label' => sfInflector::humanize(sfInflector::underscore($field))), $config['default'][$field], isset($config['list'][$field]) ? $config['list'][$field] : array()));
  77. $this->configuration['filter']['fields'][$field] = new sfModelGeneratorConfigurationField($field, array_merge($config['default'][$field], isset($config['filter'][$field]) ? $config['filter'][$field] : array()));
  78. $this->configuration['new']['fields'][$field] = new sfModelGeneratorConfigurationField($field, array_merge($formConfig, isset($config['new'][$field]) ? $config['new'][$field] : array()));
  79. $this->configuration['edit']['fields'][$field] = new sfModelGeneratorConfigurationField($field, array_merge($formConfig, isset($config['edit'][$field]) ? $config['edit'][$field] : array()));
  80. }
  81. // "virtual" fields for list
  82. foreach ($this->getListDisplay() as $field)
  83. {
  84. list($field, $flag) = sfModelGeneratorConfigurationField::splitFieldWithFlag($field);
  85. $this->configuration['list']['fields'][$field] = new sfModelGeneratorConfigurationField($field, array_merge(
  86. array('type' => 'Text', 'label' => sfInflector::humanize(sfInflector::underscore($field))),
  87. isset($config['default'][$field]) ? $config['default'][$field] : array(),
  88. isset($config['list'][$field]) ? $config['list'][$field] : array(),
  89. array('flag' => $flag)
  90. ));
  91. }
  92. // form actions
  93. foreach (array('edit', 'new') as $context)
  94. {
  95. foreach ($this->configuration[$context]['actions'] as $action => $parameters)
  96. {
  97. $this->configuration[$context]['actions'][$action] = $this->fixActionParameters($action, $parameters);
  98. }
  99. }
  100. // list actions
  101. foreach ($this->configuration['list']['actions'] as $action => $parameters)
  102. {
  103. $this->configuration['list']['actions'][$action] = $this->fixActionParameters($action, $parameters);
  104. }
  105. // list batch actions
  106. $this->configuration['list']['batch_actions'] = array();
  107. foreach ($this->getListBatchActions() as $action => $parameters)
  108. {
  109. $parameters = $this->fixActionParameters($action, $parameters);
  110. $action = 'batch'.ucfirst(0 === strpos($action, '_') ? substr($action, 1) : $action);
  111. $this->configuration['list']['batch_actions'][$action] = $parameters;
  112. }
  113. // list object actions
  114. foreach ($this->configuration['list']['object_actions'] as $action => $parameters)
  115. {
  116. $this->configuration['list']['object_actions'][$action] = $this->fixActionParameters($action, $parameters);
  117. }
  118. // list field configuration
  119. $this->configuration['list']['display'] = array();
  120. foreach ($this->getListDisplay() as $name)
  121. {
  122. list($name, $flag) = sfModelGeneratorConfigurationField::splitFieldWithFlag($name);
  123. if (!isset($this->configuration['list']['fields'][$name]))
  124. {
  125. throw new InvalidArgumentException(sprintf('The field "%s" does not exist.', $name));
  126. }
  127. $field = $this->configuration['list']['fields'][$name];
  128. $field->setFlag($flag);
  129. $this->configuration['list']['display'][$name] = $field;
  130. }
  131. // parse the %%..%% variables, remove flags and add default fields where
  132. // necessary (fixes #7578)
  133. $this->parseVariables('list', 'params');
  134. $this->parseVariables('edit', 'title');
  135. $this->parseVariables('list', 'title');
  136. $this->parseVariables('new', 'title');
  137. // action credentials
  138. $this->configuration['credentials'] = array(
  139. 'list' => array(),
  140. 'new' => array(),
  141. 'create' => array(),
  142. 'edit' => array(),
  143. 'update' => array(),
  144. 'delete' => array(),
  145. );
  146. foreach ($this->getActionsDefault() as $action => $params)
  147. {
  148. if (0 === strpos($action, '_'))
  149. {
  150. $action = substr($action, 1);
  151. }
  152. $this->configuration['credentials'][$action] = isset($params['credentials']) ? $params['credentials'] : array();
  153. $this->configuration['credentials']['batch'.ucfirst($action)] = isset($params['credentials']) ? $params['credentials'] : array();
  154. }
  155. $this->configuration['credentials']['create'] = $this->configuration['credentials']['new'];
  156. $this->configuration['credentials']['update'] = $this->configuration['credentials']['edit'];
  157. }
  158. protected function parseVariables($context, $key)
  159. {
  160. preg_match_all('/%%([^%]+)%%/', $this->configuration[$context][$key], $matches, PREG_PATTERN_ORDER);
  161. foreach ($matches[1] as $name)
  162. {
  163. list($name, $flag) = sfModelGeneratorConfigurationField::splitFieldWithFlag($name);
  164. if (!isset($this->configuration[$context]['fields'][$name]))
  165. {
  166. $this->configuration[$context]['fields'][$name] = new sfModelGeneratorConfigurationField($name, array_merge(
  167. array('type' => 'Text', 'label' => sfInflector::humanize(sfInflector::underscore($name))),
  168. isset($config['default'][$name]) ? $config['default'][$name] : array(),
  169. isset($config[$context][$name]) ? $config[$context][$name] : array(),
  170. array('flag' => $flag)
  171. ));
  172. }
  173. else
  174. {
  175. $this->configuration[$context]['fields'][$name]->setFlag($flag);
  176. }
  177. $this->configuration[$context][$key] = str_replace('%%'.$flag.$name.'%%', '%%'.$name.'%%', $this->configuration[$context][$key]);
  178. }
  179. }
  180. public function getContextConfiguration($context, $fields = null)
  181. {
  182. if (!isset($this->configuration[$context]))
  183. {
  184. throw new InvalidArgumentException(sprintf('The context "%s" does not exist.', $context));
  185. }
  186. if (null === $fields)
  187. {
  188. return $this->configuration[$context];
  189. }
  190. $f = array();
  191. foreach ($fields as $field)
  192. {
  193. $f[$field] = $this->configuration[$context]['fields'][$field];
  194. }
  195. return $f;
  196. }
  197. public function getFieldConfiguration($context, $field)
  198. {
  199. if (!isset($this->configuration[$context]))
  200. {
  201. throw new InvalidArgumentException(sprintf('The context "%s" does not exist.', $context));
  202. }
  203. if (!isset($this->configuration[$context]['fields'][$field]))
  204. {
  205. throw new InvalidArgumentException(sprintf('Field "%s" does not exist.', $field));
  206. }
  207. return $this->configuration[$context]['fields'][$field];
  208. }
  209. /**
  210. * Gets the configuration for a given field.
  211. *
  212. * @param string $key The configuration key (title.list.name for example)
  213. * @param mixed $default The default value if none has been defined
  214. * @param Boolean $escaped Whether to escape single quote (false by default)
  215. *
  216. * @return mixed The configuration value
  217. */
  218. public function getValue($key, $default = null, $escaped = false)
  219. {
  220. if (preg_match('/^(?P<context>[^\.]+)\.fields\.(?P<field>[^\.]+)\.(?P<key>.+)$/', $key, $matches))
  221. {
  222. $v = $this->getFieldConfiguration($matches['context'], $matches['field'])->getConfig($matches['key'], $default);
  223. }
  224. else if (preg_match('/^(?P<context>[^\.]+)\.(?P<key>.+)$/', $key, $matches))
  225. {
  226. $v = sfModelGeneratorConfiguration::getFieldConfigValue($this->getContextConfiguration($matches['context']), $matches['key'], $default);
  227. }
  228. else
  229. {
  230. throw new InvalidArgumentException(sprintf('Configuration key "%s" is invalid.', $key));
  231. }
  232. return $escaped ? str_replace("'", "\\'", $v) : $v;
  233. }
  234. /**
  235. * Gets the fields that represents the filters.
  236. *
  237. * If no filter.display parameter is passed in the configuration,
  238. * all the fields from the form are returned (dynamically).
  239. *
  240. * @param sfForm $form The form with the fields
  241. */
  242. public function getFormFilterFields(sfForm $form)
  243. {
  244. $config = $this->getConfig();
  245. if ($this->getFilterDisplay())
  246. {
  247. $fields = array();
  248. foreach ($this->getFilterDisplay() as $name)
  249. {
  250. list($name, $flag) = sfModelGeneratorConfigurationField::splitFieldWithFlag($name);
  251. if (!isset($this->configuration['filter']['fields'][$name]))
  252. {
  253. $this->configuration['filter']['fields'][$name] = new sfModelGeneratorConfigurationField($name, array_merge(
  254. isset($config['default'][$name]) ? $config['default'][$name] : array(),
  255. isset($config['filter'][$name]) ? $config['filter'][$name] : array(),
  256. array('is_real' => false, 'type' => 'Text', 'flag' => $flag)
  257. ));
  258. }
  259. $field = $this->configuration['filter']['fields'][$name];
  260. $field->setFlag($flag);
  261. $fields[$name] = $field;
  262. }
  263. return $fields;
  264. }
  265. $fields = array();
  266. foreach ($form->getWidgetSchema()->getPositions() as $name)
  267. {
  268. $fields[$name] = new sfModelGeneratorConfigurationField($name, array_merge(
  269. array('type' => 'Text'),
  270. isset($config['default'][$name]) ? $config['default'][$name] : array(),
  271. isset($config['filter'][$name]) ? $config['filter'][$name] : array(),
  272. array('is_real' => false)
  273. ));
  274. }
  275. return $fields;
  276. }
  277. /**
  278. * Gets the fields that represents the form.
  279. *
  280. * If no form.display parameter is passed in the configuration,
  281. * all the fields from the form are returned (dynamically).
  282. *
  283. * @param sfForm $form The form with the fields
  284. * @param string $context The display context
  285. */
  286. public function getFormFields(sfForm $form, $context)
  287. {
  288. $config = $this->getConfig();
  289. $method = sprintf('get%sDisplay', ucfirst($context));
  290. if (!$fieldsets = $this->$method())
  291. {
  292. $fieldsets = $this->getFormDisplay();
  293. }
  294. if ($fieldsets)
  295. {
  296. $fields = array();
  297. // with fieldsets?
  298. if (!is_array(reset($fieldsets)))
  299. {
  300. $fieldsets = array('NONE' => $fieldsets);
  301. }
  302. foreach ($fieldsets as $fieldset => $names)
  303. {
  304. if (!$names)
  305. {
  306. continue;
  307. }
  308. $fields[$fieldset] = array();
  309. foreach ($names as $name)
  310. {
  311. list($name, $flag) = sfModelGeneratorConfigurationField::splitFieldWithFlag($name);
  312. if (!isset($this->configuration[$context]['fields'][$name]))
  313. {
  314. $this->configuration[$context]['fields'][$name] = new sfModelGeneratorConfigurationField($name, array_merge(
  315. isset($config['default'][$name]) ? $config['default'][$name] : array(),
  316. isset($config['form'][$name]) ? $config['form'][$name] : array(),
  317. isset($config[$context][$name]) ? $config[$context][$name] : array(),
  318. array('is_real' => false, 'type' => 'Text', 'flag' => $flag)
  319. ));
  320. }
  321. $field = $this->configuration[$context]['fields'][$name];
  322. $field->setFlag($flag);
  323. $fields[$fieldset][$name] = $field;
  324. }
  325. }
  326. return $fields;
  327. }
  328. $fields = array();
  329. foreach ($form->getWidgetSchema()->getPositions() as $name)
  330. {
  331. $fields[$name] = new sfModelGeneratorConfigurationField($name, array_merge(
  332. array('type' => 'Text'),
  333. isset($config['default'][$name]) ? $config['default'][$name] : array(),
  334. isset($config['form'][$name]) ? $config['form'][$name] : array(),
  335. isset($config[$context][$name]) ? $config[$context][$name] : array(),
  336. array('is_real' => false)
  337. ));
  338. }
  339. return array('NONE' => $fields);
  340. }
  341. /**
  342. * Gets the value for a given key.
  343. *
  344. * @param array $config The configuration
  345. * @param string $key The key name
  346. * @param mixed $default The default value
  347. *
  348. * @return mixed The key value
  349. */
  350. static public function getFieldConfigValue($config, $key, $default = null)
  351. {
  352. $ref =& $config;
  353. $parts = explode('.', $key);
  354. $count = count($parts);
  355. for ($i = 0; $i < $count; $i++)
  356. {
  357. $partKey = $parts[$i];
  358. if (!isset($ref[$partKey]))
  359. {
  360. return $default;
  361. }
  362. if ($count == $i + 1)
  363. {
  364. return $ref[$partKey];
  365. }
  366. else
  367. {
  368. $ref =& $ref[$partKey];
  369. }
  370. }
  371. return $default;
  372. }
  373. public function getCredentials($action)
  374. {
  375. if (0 === strpos($action, '_'))
  376. {
  377. $action = substr($action, 1);
  378. }
  379. return isset($this->configuration['credentials'][$action]) ? $this->configuration['credentials'][$action] : array();
  380. }
  381. public function getPager($model)
  382. {
  383. $class = $this->getPagerClass();
  384. return new $class($model, $this->getPagerMaxPerPage());
  385. }
  386. /**
  387. * Gets a new form object.
  388. *
  389. * @param mixed $object
  390. * @param array $options An array of options to merge with the options returned by getFormOptions()
  391. *
  392. * @return sfForm
  393. */
  394. public function getForm($object = null, $options = array())
  395. {
  396. $class = $this->getFormClass();
  397. return new $class($object, array_merge($this->getFormOptions(), $options));
  398. }
  399. public function getFormOptions()
  400. {
  401. return array();
  402. }
  403. public function getFilterForm($filters)
  404. {
  405. $class = $this->getFilterFormClass();
  406. return new $class($filters, $this->getFilterFormOptions());
  407. }
  408. public function getFilterFormOptions()
  409. {
  410. return array();
  411. }
  412. public function getFilterDefaults()
  413. {
  414. return array();
  415. }
  416. protected function mapFieldName(sfModelGeneratorConfigurationField $field)
  417. {
  418. return $field->getName();
  419. }
  420. protected function fixActionParameters($action, $parameters)
  421. {
  422. if (null === $parameters)
  423. {
  424. $parameters = array();
  425. }
  426. if (!isset($parameters['params']))
  427. {
  428. $parameters['params'] = array();
  429. }
  430. if ('_delete' == $action && !isset($parameters['confirm']))
  431. {
  432. $parameters['confirm'] = 'Are you sure?';
  433. }
  434. $parameters['class_suffix'] = strtolower('_' == $action[0] ? substr($action, 1) : $action);
  435. // merge with defaults
  436. $defaults = $this->getActionsDefault();
  437. if (isset($defaults[$action]))
  438. {
  439. $parameters = array_merge($defaults[$action], $parameters);
  440. }
  441. if (isset($parameters['label']))
  442. {
  443. $label = $parameters['label'];
  444. }
  445. else if ('_' != $action[0])
  446. {
  447. $label = $action;
  448. }
  449. else
  450. {
  451. $label = '_list' == $action ? 'Back to list' : substr($action, 1);
  452. }
  453. $parameters['label'] = sfInflector::humanize($label);
  454. return $parameters;
  455. }
  456. protected function getConfig()
  457. {
  458. return array(
  459. 'default' => $this->getFieldsDefault(),
  460. 'list' => $this->getFieldsList(),
  461. 'filter' => $this->getFieldsFilter(),
  462. 'form' => $this->getFieldsForm(),
  463. 'new' => $this->getFieldsNew(),
  464. 'edit' => $this->getFieldsEdit(),
  465. );
  466. }
  467. }

Debug toolbar