Skip to content

Commit

Permalink
DcaUtil::getConfigByArrayOrCallbackOrFunction throws ErrorException i…
Browse files Browse the repository at this point in the history
…f not enought context, FormUtil::prepareSpecialValueForOutput catch this exception
  • Loading branch information
Rico Kaltofen committed Feb 20, 2018
1 parent 264accd commit 96419aa
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 66 deletions.
114 changes: 58 additions & 56 deletions src/Dca/DcaUtil.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@

class DcaUtil
{
const PROPERTY_SESSION_ID = 'sessionID';
const PROPERTY_AUTHOR = 'author';
const PROPERTY_SESSION_ID = 'sessionID';
const PROPERTY_AUTHOR = 'author';
const PROPERTY_AUTHOR_TYPE = 'authorType';

const AUTHOR_TYPE_NONE = 'none';
const AUTHOR_TYPE_NONE = 'none';
const AUTHOR_TYPE_MEMBER = 'member';
const AUTHOR_TYPE_USER = 'user';
const AUTHOR_TYPE_USER = 'user';

/** @var ContaoFrameworkInterface */
protected $framework;
Expand All @@ -48,19 +48,21 @@ public function __construct(ContaoFrameworkInterface $framework)
* @param array $arguments
*
* @return mixed|null The value retrieved in the way mentioned above or null
*
* @throws \ErrorException When the callback has not enough context, for example no BackendUser is available
*/
public function getConfigByArrayOrCallbackOrFunction(array $array, $property, array $arguments = [])
{
if (isset($array[$property])) {
return $array[$property];
}

if (!isset($array[$property.'_callback'])) {
if (!isset($array[$property . '_callback'])) {
return null;
}

if (is_array($array[$property.'_callback'])) {
$callback = $array[$property.'_callback'];
if (is_array($array[$property . '_callback'])) {
$callback = $array[$property . '_callback'];

if (!isset($callback[0]) || !isset($callback[1]) || !class_exists($callback[0])) {
return null;
Expand All @@ -73,8 +75,8 @@ public function getConfigByArrayOrCallbackOrFunction(array $array, $property, ar
}

return call_user_func_array([$instance, $callback[1]], $arguments);
} elseif (is_callable($array[$property.'_callback'])) {
return call_user_func_array($array[$property.'_callback'], $arguments);
} elseif (is_callable($array[$property . '_callback'])) {
return call_user_func_array($array[$property . '_callback'], $arguments);
}

return null;
Expand Down Expand Up @@ -116,7 +118,7 @@ public function setDateAddedOnCopy($insertId, DataContainer $dc)
* Returns a list of fields as an option array for dca fields.
*
* @param string $table
* @param array $options
* @param array $options
*
* @return array
*/
Expand Down Expand Up @@ -144,7 +146,7 @@ public function getFields(string $table, array $options = []): array
if (isset($options['localizeLabels']) && !$options['localizeLabels']) {
$fields[$name] = $name;
} else {
$fields[$name] = ($data['label'][0] ?: $name).($data['label'][0] ? ' ['.$name.']' : '');
$fields[$name] = ($data['label'][0] ?: $name) . ($data['label'][0] ? ' [' . $name . ']' : '');
}
}

Expand All @@ -158,10 +160,10 @@ public function getFields(string $table, array $options = []): array
/**
* Adds an override selector to every field in $fields to the dca associated with $destinationTable.
*
* @param array $fields
* @param array $fields
* @param string $sourceTable
* @param string $destinationTable
* @param array $options
* @param array $options
*/
public function addOverridableFields(array $fields, string $sourceTable, string $destinationTable, array $options = [])
{
Expand All @@ -175,14 +177,14 @@ public function addOverridableFields(array $fields, string $sourceTable, string

foreach ($fields as $field) {
// add override boolean field
$overrideFieldname = 'override'.ucfirst($field);
$overrideFieldname = 'override' . ucfirst($field);

$destinationDca['fields'][$overrideFieldname] = [
'label' => &$GLOBALS['TL_LANG'][$destinationTable][$overrideFieldname],
'exclude' => true,
'label' => &$GLOBALS['TL_LANG'][$destinationTable][$overrideFieldname],
'exclude' => true,
'inputType' => 'checkbox',
'eval' => ['tl_class' => 'w50', 'submitOnChange' => true, 'isOverrideSelector' => true],
'sql' => "char(1) NOT NULL default ''",
'eval' => ['tl_class' => 'w50', 'submitOnChange' => true, 'isOverrideSelector' => true],
'sql' => "char(1) NOT NULL default ''",
];

if (isset($options['checkboxDcaEvalOverride']) && is_array($options['checkboxDcaEvalOverride'])) {
Expand Down Expand Up @@ -219,15 +221,15 @@ public function addOverridableFields(array $fields, string $sourceTable, string
* model instance is only used if it's either the first instance in $arrInstances or "overrideFieldname" is set to true
* in the instance.
*
* @param string $property The property name to retrieve
* @param array $instances An array of instances in ascending priority. Instances can be passed in the following form:
* @param string $property The property name to retrieve
* @param array $instances An array of instances in ascending priority. Instances can be passed in the following form:
* ['tl_some_table', $instanceId] or $objInstance
*
* @return mixed
*/
public function getOverridableProperty(string $property, array $instances)
{
$result = null;
$result = null;
$preparedInstances = [];

// prepare instances
Expand All @@ -242,7 +244,7 @@ public function getOverridableProperty(string $property, array $instances)
}

foreach ($preparedInstances as $i => $preparedInstance) {
if (0 == $i || $preparedInstance->{'override'.ucfirst($property)}) {
if (0 == $i || $preparedInstance->{'override' . ucfirst($property)}) {
$result = $preparedInstance->{$property};
}
}
Expand All @@ -266,7 +268,7 @@ public function flattenPaletteForSubEntities(string $table, array $overridableFi
{
Controller::loadDataContainer($table);

$dca = &$GLOBALS['TL_DCA'][$table];
$dca = &$GLOBALS['TL_DCA'][$table];
$arrayUtil = System::getContainer()->get('huh.utils.array');

// palette
Expand All @@ -277,12 +279,12 @@ public function flattenPaletteForSubEntities(string $table, array $overridableFi
if (in_array($field, $dca['palettes']['__selector__'], true)) {
// flatten concatenated type selectors
foreach ($dca['subpalettes'] as $selector => $subPaletteFields) {
if (false !== strpos($selector, $field.'_')) {
if (false !== strpos($selector, $field . '_')) {
if ($dca['subpalettes'][$selector]) {
$subPaletteFields = explode(',', $dca['subpalettes'][$selector]);

foreach (array_reverse($subPaletteFields) as $subPaletteField) {
$dca['palettes']['default'] = str_replace($field, $field.','.$subPaletteField, $dca['palettes']['default']);
$dca['palettes']['default'] = str_replace($field, $field . ',' . $subPaletteField, $dca['palettes']['default']);
}
}

Expand All @@ -297,7 +299,7 @@ public function flattenPaletteForSubEntities(string $table, array $overridableFi
$subPaletteFields = explode(',', $dca['subpalettes'][$field]);

foreach (array_reverse($subPaletteFields) as $subPaletteField) {
$dca['palettes']['default'] = str_replace($field, $field.','.$subPaletteField, $dca['palettes']['default']);
$dca['palettes']['default'] = str_replace($field, $field . ',' . $subPaletteField, $dca['palettes']['default']);
}

// remove nested field in order to avoid its normal "selector" behavior
Expand All @@ -307,18 +309,18 @@ public function flattenPaletteForSubEntities(string $table, array $overridableFi
}
}

$dca['palettes']['default'] = str_replace($field, 'override'.ucfirst($field), $dca['palettes']['default']);
$dca['palettes']['default'] = str_replace($field, 'override' . ucfirst($field), $dca['palettes']['default']);
}
}

/**
* Generate an alias.
*
* @param mixed $alias The current alias (if available)
* @param int $id The entity's id
* @param string $table The entity's table
* @param string $title The value to use as a base for the alias
* @param bool $keepUmlauts Set to true if German umlauts should be kept
* @param mixed $alias The current alias (if available)
* @param int $id The entity's id
* @param string $table The entity's table
* @param string $title The value to use as a base for the alias
* @param bool $keepUmlauts Set to true if German umlauts should be kept
*
* @throws \Exception
*
Expand All @@ -331,7 +333,7 @@ public function generateAlias(string $alias, int $id, string $table, string $tit
// Generate alias if there is none
if (empty($alias)) {
$autoAlias = true;
$alias = StringUtil::generateAlias($title);
$alias = StringUtil::generateAlias($title);
}

if (!$keepUmlauts) {
Expand All @@ -354,7 +356,7 @@ public function generateAlias(string $alias, int $id, string $table, string $tit

// Add ID to alias
if ($existingAlias->numRows && $existingAlias->id != $id && $autoAlias || !$alias) {
$alias .= '-'.$id;
$alias .= '-' . $id;
}

return $alias;
Expand All @@ -365,45 +367,45 @@ public function addAuthorFieldAndCallback(string $table)
Controller::loadDataContainer($table);

// callbacks
$GLOBALS['TL_DCA'][$table]['config']['oncreate_callback']['setAuthorIDOnCreate'] = ['huh.utils.dca', 'setAuthorIDOnCreate'];
$GLOBALS['TL_DCA'][$table]['config']['oncreate_callback']['setAuthorIDOnCreate'] = ['huh.utils.dca', 'setAuthorIDOnCreate'];
$GLOBALS['TL_DCA'][$table]['config']['onload_callback']['modifyAuthorPaletteOnLoad'] = ['huh.utils.dca', 'modifyAuthorPaletteOnLoad', true];

// fields
$GLOBALS['TL_DCA'][$table]['fields'][static::PROPERTY_AUTHOR_TYPE] = [
'label' => &$GLOBALS['TL_LANG']['MSC']['utilsBundle']['authorType'],
'exclude' => true,
'filter' => true,
'default' => static::AUTHOR_TYPE_NONE,
'label' => &$GLOBALS['TL_LANG']['MSC']['utilsBundle']['authorType'],
'exclude' => true,
'filter' => true,
'default' => static::AUTHOR_TYPE_NONE,
'inputType' => 'select',
'options' => [
'options' => [
static::AUTHOR_TYPE_NONE,
static::AUTHOR_TYPE_MEMBER,
static::AUTHOR_TYPE_USER,
],
'reference' => $GLOBALS['TL_LANG']['MSC']['utilsBundle']['authorType'],
'eval' => ['doNotCopy' => true, 'submitOnChange' => true, 'mandatory' => true, 'tl_class' => 'w50 clr'],
'sql' => "varchar(255) NOT NULL default 'none'",
'eval' => ['doNotCopy' => true, 'submitOnChange' => true, 'mandatory' => true, 'tl_class' => 'w50 clr'],
'sql' => "varchar(255) NOT NULL default 'none'",
];

$GLOBALS['TL_DCA'][$table]['fields'][static::PROPERTY_AUTHOR] = [
'label' => &$GLOBALS['TL_LANG']['MSC']['utilsBundle']['author'],
'exclude' => true,
'search' => true,
'filter' => true,
'inputType' => 'select',
'label' => &$GLOBALS['TL_LANG']['MSC']['utilsBundle']['author'],
'exclude' => true,
'search' => true,
'filter' => true,
'inputType' => 'select',
'options_callback' => function () {
return \Contao\System::getContainer()->get('huh.utils.choice.model_instance')->getCachedChoices([
'dataContainer' => 'tl_member',
'labelPattern' => '%firstname% %lastname% (ID %id%)',
'labelPattern' => '%firstname% %lastname% (ID %id%)',
]);
},
'eval' => [
'doNotCopy' => true,
'chosen' => true,
'eval' => [
'doNotCopy' => true,
'chosen' => true,
'includeBlankOption' => true,
'tl_class' => 'w50',
'tl_class' => 'w50',
],
'sql' => "int(10) unsigned NOT NULL default '0'",
'sql' => "int(10) unsigned NOT NULL default '0'",
];
}

Expand All @@ -422,12 +424,12 @@ public function setAuthorIDOnCreate(string $table, int $id, array $row, DataCont
if (System::getContainer()->get('huh.utils.container')->isFrontend()) {
if (FE_USER_LOGGED_IN) {
$model->{static::PROPERTY_AUTHOR_TYPE} = static::AUTHOR_TYPE_MEMBER;
$model->{static::PROPERTY_AUTHOR} = $this->framework->getAdapter(FrontendUser::class)->getInstance()->id;
$model->{static::PROPERTY_AUTHOR} = $this->framework->getAdapter(FrontendUser::class)->getInstance()->id;
$model->save();
}
} else {
$model->{static::PROPERTY_AUTHOR_TYPE} = static::AUTHOR_TYPE_USER;
$model->{static::PROPERTY_AUTHOR} = $this->framework->getAdapter(BackendUser::class)->getInstance()->id;
$model->{static::PROPERTY_AUTHOR} = $this->framework->getAdapter(BackendUser::class)->getInstance()->id;
$model->save();
}
}
Expand Down Expand Up @@ -457,7 +459,7 @@ public function modifyAuthorPaletteOnLoad(DataContainer $dc)
$dca['fields']['author']['options_callback'] = function () {
return \Contao\System::getContainer()->get('huh.utils.choice.model_instance')->getCachedChoices([
'dataContainer' => 'tl_user',
'labelPattern' => '%name% (ID %id%)',
'labelPattern' => '%name% (ID %id%)',
]);
};
}
Expand Down
25 changes: 15 additions & 10 deletions src/Form/FormUtil.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ public function __construct(ContaoFrameworkInterface $framework)
/**
* Prepares a special field's value. If an array is inserted, the function will call itself recursively.
*
* @param string $field
* @param string $field
* @param $value
* @param DataContainer $dc
* @param array $config
* @param array $config
*
* Possible config options:
* - preserveEmptyArrayValues -> preserves array values even if they're empty
Expand Down Expand Up @@ -91,12 +91,12 @@ public function prepareSpecialValueForOutput(string $field, $value, DataContaine
foreach ($row as $fieldName => $fieldValue) {
$dca = $data['eval']['multiColumnEditor']['fields'][$fieldName];

$fields[] = ($dca['label'][0] ?: $fieldName).': '.$this->prepareSpecialValueForOutput($fieldName, $fieldValue, $dc, array_merge($config, [
'_dcaOverride' => $dca,
$fields[] = ($dca['label'][0] ?: $fieldName) . ': ' . $this->prepareSpecialValueForOutput($fieldName, $fieldValue, $dc, array_merge($config, [
'_dcaOverride' => $dca,
]));
}

$rows[] = '['.implode(', ', $fields).']';
$rows[] = '[' . implode(', ', $fields) . ']';
}

$value = implode(', ', $rows);
Expand Down Expand Up @@ -142,8 +142,13 @@ public function prepareSpecialValueForOutput(string $field, $value, DataContaine
if ((!isset($config['skipOptionCaching']) || !$config['skipOptionCaching']) && null !== $this->optionsCache) {
$options = $this->optionsCache;
} else {
$options = System::getContainer()->get('huh.utils.dca')->getConfigByArrayOrCallbackOrFunction($data, 'options', [$dc]);
$this->optionsCache = $options;
try {
$options = System::getContainer()->get('huh.utils.dca')->getConfigByArrayOrCallbackOrFunction($data, 'options', [$dc]);
} catch (\ErrorException $e) {
$options = [];
}

$this->optionsCache = !is_array($options) ? [] : $options;
}

// foreignKey
Expand All @@ -161,11 +166,11 @@ public function prepareSpecialValueForOutput(string $field, $value, DataContaine
}
} elseif ('cfgTags' == $data['inputType']) {
$collection = $cfgTagModel->findBy(['source=?', 'id = ?'], [$data['eval']['tagsManager'], $value]);
$value = null;
$value = null;

if (null !== $collection) {
$result = $collection->fetchEach('name');
$value = implode(', ', $result);
$value = implode(', ', $result);
}
} elseif ('date' == $rgxp) {
$value = Date::parse(Config::get('dateFormat'), $value);
Expand All @@ -175,7 +180,7 @@ public function prepareSpecialValueForOutput(string $field, $value, DataContaine
$value = Date::parse(Config::get('datimFormat'), $value);
} elseif (Validator::isBinaryUuid($value)) {
$strPath = System::getContainer()->get('huh.utils.file')->getPathFromUuid($value);
$value = $strPath ? Environment::get('url').'/'.$strPath : StringUtil::binToUuid($value);
$value = $strPath ? Environment::get('url') . '/' . $strPath : StringUtil::binToUuid($value);
} // Replace boolean checkbox value with "yes" and "no"
else {
if ((isset($data['eval']['isBoolean']) && $data['eval']['isBoolean']) || ('checkbox' == $data['inputType'] && !$data['eval']['multiple'])) {
Expand Down

0 comments on commit 96419aa

Please sign in to comment.