Commit adc006aa authored by Tristan Olive's avatar Tristan Olive

Save project preferences in group and compound elements according to schema...

Save project preferences in group and compound elements according to schema update; remove obsolete schema validation code

(DBOINCP-108)
parent 22dd13cc
......@@ -303,11 +303,17 @@ function boincwork_format_project_specific_prefs_data($values, $xml = array()) {
case 'compound':
foreach ($elements as $element) {
$name = $element['@attributes']['name'];
$default[$name] = boincwork_format_project_specific_prefs_data($values, $element);
$default[$name]['@attributes'] = boincwork_format_project_specific_prefs_data($values, $element['attributes']);
}
$defaults += $default;
break;
case 'group':
foreach ($elements as $element) {
$defaults += boincwork_format_project_specific_prefs_data($values, $element);
}
break;
case 'text':
case 'radio':
case 'dropdown':
......@@ -341,368 +347,6 @@ function boincwork_format_project_specific_prefs_data($values, $xml = array()) {
return $defaults;
}
/**
* Validate project specific preferences XML.
* This implements the project specific preferences schema
*/
function boincwork_validate_prefs($config, $type = null, $xml_path = '') {
if ($type AND $xml_path) {
$xml_path .= "::{$type}";
}
switch ($type) {
case 'entitytype':
if (!is_string($config)) {
drupal_set_message(t('@xml_path entitytype must be a string',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
$datatypes = array(
'element',
'attribute'
);
if (!in_array($config, $datatypes)) {
drupal_set_message(t('@xml_path invalid entitytype',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
break;
case 'lang':
if (!is_string($config)) {
drupal_set_message(t('@xml_path language must be a string',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
$available_languages = array(
'en_US',
'de_DE'
);
if (!in_array($config, $available_languages)) {
drupal_set_message(t('@xml_path invalid language',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
break;
case 'datatype':
if (!is_string($config)) {
drupal_set_message(t('@xml_path datatype must be a string',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
$datatypes = array(
'text',
'integer',
'float'
);
if (!in_array($config, $datatypes)) {
drupal_set_message(t('@xml_path invalid datatype',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
break;
case 'title':
case 'description':
if (is_numeric(key($config))) {
drupal_set_message(t('@xml_path element has multiple @types',
array('@xml_path' => $xml_path, '@type' => $type)), 'warning');
return false;
}
if (isset($config['@attributes'])) {
if (isset($config['@attributes']['lang']) AND
!boincwork_validate_prefs($config['@attributes']['lang'], 'lang',
$xml_path)) {
return false;
}
if (!is_string($config['@value'])) {
drupal_set_message(t('@xml_path @type should be a string',
array('@xml_path' => $xml_path, '@type' => $type)), 'warning');
return false;
}
}
else {
if (!is_string($config)) {
drupal_set_message(t('@xml_path @type should be a string',
array('@xml_path' => $xml_path, '@type' => $type)), 'warning');
return false;
}
}
break;
case 'item':
if (isset($config['@attributes'])) {
if (!is_string($config['@value'])) {
drupal_set_message(t('@xml_path value of @type should be a string',
array('@xml_path' => $xml_path, '@type' => $type)), 'warning');
return false;
}
}
else {
if (!is_string($config)) {
drupal_set_message(t('@xml_path value of @type should be a string',
array('@xml_path' => $xml_path, '@type' => $type)), 'warning');
return false;
}
}
break;
case 'app':
// Each app needs an ID
if (!isset($config['@attributes']) OR
!isset($config['@attributes']['id'])) {
drupal_set_message(t('@xml_path @type element must have an ID',
array('@xml_path' => $xml_path, '@type' => $type)), 'warning');
return false;
}
if (!is_numeric($config['@attributes']['id']) OR
$config['@attributes']['id'] < 1) {
drupal_set_message(t('@xml_path @type ID must a positive integer',
array('@xml_path' => $xml_path, '@type' => $type)), 'warning');
return false;
}
break;
case 'items':
if (!isset($config['item'])) {
drupal_set_message(t('@xml_path element must contain an item',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
if (!is_numeric(key($config['item']))) {
$config['item'] = array($config['item']);
}
// Ensure only one item is selected
$items_selected = 0;
foreach ($config['item'] as $item) {
if (isset($item['@attributes']['selected']) AND
$item['@attributes']['selected'] = TRUE) {
$items_selected++;
}
}
if ($items_selected != 1) {
drupal_set_message(t('@xml_path exactly one item must be selected',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
break;
case 'component':
if (!isset($config['title'])) {
drupal_set_message(t('@xml_path title not set',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
if (!boincwork_validate_prefs($config['title'], 'title', $xml_path)) {
return false;
}
if (isset($config['description']) AND
!boincwork_validate_prefs($config['description'], 'description',
$xml_path)) {
return false;
}
if (!isset($config['@attributes']) OR
!isset($config['@attributes']['name'])) {
drupal_set_message(t('@xml_path no name is set',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
if (!is_string($config['@attributes']['name'])) {
drupal_set_message(t('@xml_path name must be a string',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
break;
case 'text':
if (!is_numeric(key($config))) {
$config = array($config);
}
foreach ($config as $text) {
// Check standard component validations
if (!boincwork_validate_prefs($text, 'component', $xml_path)) {
return false;
}
// Then check text specific attributes
if (!isset($text['@attributes']['datatype']) OR
!boincwork_validate_prefs($text['@attributes']['datatype'],
'datatype', $xml_path)) {
return false;
}
if (!isset($text['@attributes']['default']) OR
!is_string($text['@attributes']['default'])) {
drupal_set_message(t('@xml_path default value must be a string',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
// Optional attributes
if (isset($text['@attributes']['min']) AND
!is_numeric($text['@attributes']['min'])) {
drupal_set_message(t('@xml_path min must be an integer',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
if (isset($text['@attributes']['max']) AND
!is_numeric($text['@attributes']['max'])) {
drupal_set_message(t('@xml_path max must be an integer',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
}
break;
case 'boolean':
if (!is_numeric(key($config))) {
$config = array($config);
}
foreach ($config as $boolean) {
// Check standard component validation
if (!boincwork_validate_prefs($boolean, 'component', $xml_path)) {
return false;
}
}
break;
case 'radio':
if (!is_numeric(key($config))) {
$config = array($config);
}
foreach ($config as $radio) {
// Check standard component validation
if (!boincwork_validate_prefs($radio, 'component', $xml_path)) {
return false;
}
if (!isset($radio['items']) OR is_numeric(key($radio['items']))) {
drupal_set_message(t('@xml_path must have exactly one items list',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
if (!boincwork_validate_prefs($radio['items'], 'items', $xml_path)) {
return false;
}
}
break;
case 'dropdown':
if (!is_numeric(key($config))) {
$config = array($config);
}
foreach ($config as $dropdown) {
// Check standard component validation
if (!boincwork_validate_prefs($dropdown, 'component', $xml_path)) {
return false;
}
if (!isset($dropdown['items']) OR is_numeric(key($dropdown['items']))) {
drupal_set_message(t('@xml_path must have exactly one items list',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
if (!boincwork_validate_prefs($dropdown['items'], 'items', $xml_path)) {
return false;
}
}
break;
case 'apps':
// The apps element must have a title
if (!isset($config['title'])) {
drupal_set_message(t('@xml_path title is required',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
elseif (!boincwork_validate_prefs($config['title'], 'title')) {
return false;
}
// ...and at least one app
if (!isset($config['app'])) {
drupal_set_message(t('@xml_path must have at least one app',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
elseif (!is_numeric(key($config['app']))) {
$config['app'] = array($config['app']);
}
foreach ($config['app'] as $app) {
if (!boincwork_validate_prefs($app, 'app')) {
return false;
}
}
break;
case 'compound':
if (!is_numeric(key($config))) {
$config = array($config);
}
foreach ($config as $compound) {
// Each compound element must have a name...
if (!isset($compound['@attributes']) OR
!isset($compound['@attributes']['name']) OR
!is_string($compound['@attributes']['name']) OR
$compound['@attributes']['name'] == '') {
drupal_set_message(t('@xml_path has no name',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
// ...and a title...
if (!isset($compound['title'])) {
drupal_set_message(t('@xml_path @name element has no title',
array('@xml_path' => $xml_path, '@name' => $compound['@attributes']['name'])), 'warning');
return false;
}
elseif (is_numeric(key($compound['title']))) {
drupal_set_message(t('@xml_path @name element has multiple titles',
array('@xml_path' => $xml_path, '@name' => $compound['@attributes']['name'])), 'warning');
return false;
}
elseif (!boincwork_validate_prefs($compound['title'], 'title', $xml_path)) {
return false;
}
// ...and at least one of these elements as a child
if (!isset($compound['text']) AND
!isset($compound['boolean']) AND
!isset($compound['radio']) AND
!isset($compound['dropdown'])) {
drupal_set_message(t('@xml_path @name element is incomplete',
array('@xml_path' => $xml_path, '@name' => $compound['@attributes']['name'])), 'warning');
return false;
}
// Now recursively validate...
foreach ($compound as $type => $element) {
if (!boincwork_validate_prefs($element, $type, $xml_path)) {
return false;
}
}
}
break;
case 'root':
// Root must have at least one of these elements
if (!isset($config['text']) AND
!isset($config['boolean']) AND
!isset($config['radio']) AND
!isset($config['dropdown']) AND
!isset($config['apps']) AND
!isset($config['compound'])) {
drupal_set_message(t('prefs_xml::document content is required',
array('@xml_path' => $xml_path)), 'warning');
return false;
}
// Recursively validate the document...
foreach ($config as $type => $element) {
if (!boincwork_validate_prefs($element, $type, 'prefs_xml')) {
return false;
}
}
break;
default:
// Don't validate that which doesn't explicitly require validation, for
// recursion (i.e. '@attributes' keys and the like, which are handled
// by parent validation)
}
return true;
}
/**
* Add an element to the form based on its definition
*/
......@@ -802,6 +446,7 @@ function boincwork_generate_prefs_element(&$form, $type, $elements, $user_prefs
case 'radio':
case 'dropdown':
if (!is_numeric(key($elements))) {
$elements = array($elements);
}
......@@ -828,6 +473,7 @@ function boincwork_generate_prefs_element(&$form, $type, $elements, $user_prefs
if (isset($element['description'])) {
$description = is_array($element['description']) ? $element['description']['@value'] : $element['description'];
}
$user_pref = $user_prefs;
$entitytype = isset($element['@attributes']['entitytype']) ? $element['@attributes']['entitytype'] : 'element';
if ($entitytype == 'attribute') {
$user_pref = $user_prefs['@attributes'];
......@@ -928,7 +574,7 @@ function boincwork_generate_prefs_element(&$form, $type, $elements, $user_prefs
);
// Recursively populate the compound element
foreach ($element['attributes'] as $child_type => $child) {
boincwork_generate_prefs_element($form[$name], $child_type, $child, $user_prefs[$name]);
boincwork_generate_prefs_element($form[$name], $child_type, $child, $user_prefs[$name]['@attributes']);
}
}
break;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment