Extension ext-surfbar continued, fixes:
authorRoland Häder <roland@mxchange.org>
Mon, 11 Jul 2011 09:25:56 +0000 (09:25 +0000)
committerRoland Häder <roland@mxchange.org>
Mon, 11 Jul 2011 09:25:56 +0000 (09:25 +0000)
- Menu point 'list_surfbar_urls' is now fully generated from XML meta data
  templates
- Fixes in various places
- TODOs.txt updated

31 files changed:
DOCS/TODOs.txt
inc/callback-functions.php
inc/config-functions.php
inc/daily/daily_profile.php
inc/filter-functions.php
inc/language/de.php
inc/libs/admins_functions.php
inc/libs/beg_functions.php
inc/libs/doubler_functions.php
inc/libs/order_functions.php
inc/libs/profile_functions.php
inc/libs/surfbar_functions.php
inc/libs/transfer_functions.php
inc/libs/wernis_functions.php
inc/modules/admin/admin-inc.php
inc/modules/admin/what-list_surfbar_urls.php
inc/template-functions.php
inc/wrapper-functions.php
inc/xml-functions.php
templates/de/html/admin/admin_surfbar_url_stats_row.tpl
templates/xml/admin/admin_delete_do_surfbar_urls.xml
templates/xml/admin/admin_delete_show_surfbar_urls.xml
templates/xml/admin/admin_edit_do_surfbar_urls.xml
templates/xml/admin/admin_edit_show_surfbar_urls.xml
templates/xml/admin/admin_list_surfbar_urls.xml [new file with mode: 0644]
templates/xml/admin/admin_lock_do_surfbar_urls.xml
templates/xml/admin/admin_lock_show_surfbar_urls.xml
templates/xml/admin/admin_undelete_do_surfbar_urls.xml
templates/xml/admin/admin_undelete_show_surfbar_urls.xml
templates/xml/admin_data_template.xml
templates/xml/admin_list_data_template.xml [new file with mode: 0644]

index e75e4b1..ffe0330 100644 (file)
@@ -98,6 +98,8 @@
 ./inc/mails/doubler_mails.php:53:// @TODO Can this be rewritten to a filter?
 ./inc/module-functions.php:267:                        // @TODO Nothing helped???
 ./inc/module-functions.php:308:                        // @TODO Rewrite this to a filter
+./inc/modules/admin/admin-inc.php:1159:                // @TODO WHERE is not yet supported
+./inc/modules/admin/admin-inc.php:1213:                                // @TODO If we can rewrite the EL sub-system to support more than one parameter, this call_user_func_array() can be avoided
 ./inc/modules/admin/admin-inc.php:171:         // @TODO This and the next getCurrentAdminId() call might be moved into the templates?
 ./inc/modules/admin/admin-inc.php:242:         // @TODO This can be rewritten into a filter
 ./inc/modules/admin/admin-inc.php:274:         // @TODO Rewrite this to $content = SQL_FETCHARRAY()
 ./inc/mysql-manager.php:44:// @TODO Can we cache this?
 ./inc/purge/purge-inact.php:55:        // @TODO Rewrite these if() blocks to a filter
 ./inc/revision-functions.php:169:// @TODO This function does also set and get in 'cache_array'
-./inc/template-functions.php:1058:                     // @TODO Deprecate this thing
-./inc/template-functions.php:1069:                     // @TODO Deprecate this thing
-./inc/template-functions.php:1162:     // @TODO This can be easily moved out after the merge from EL branch to this is complete
-./inc/template-functions.php:1195:             // @TODO Add a little more infos here
-./inc/template-functions.php:1506:// @TODO Lame description for this function
-./inc/template-functions.php:1528:                     // @TODO Move this in a filter
+./inc/template-functions.php:1063:                     // @TODO Deprecate this thing
+./inc/template-functions.php:1074:                     // @TODO Deprecate this thing
+./inc/template-functions.php:1167:     // @TODO This can be easily moved out after the merge from EL branch to this is complete
+./inc/template-functions.php:1200:             // @TODO Add a little more infos here
+./inc/template-functions.php:1511:// @TODO Lame description for this function
+./inc/template-functions.php:1533:                     // @TODO Move this in a filter
 ./inc/template-functions.php:189:       * @TODO On some pages this is buggy
-./inc/template-functions.php:265:      // @TODO Remove this sanity-check if all is fine
-./inc/template-functions.php:586:// @TODO $simple/$constants are deprecated
-./inc/template-functions.php:612:      // @TODO Do only use $content and deprecate $GLOBALS and $DATA in templates
+./inc/template-functions.php:266:              // @TODO Remove this sanity-check if all is fine
+./inc/template-functions.php:591:// @TODO $simple/$constants are deprecated
+./inc/template-functions.php:617:      // @TODO Do only use $content and deprecate $GLOBALS and $DATA in templates
 ./inc/wrapper-functions.php:130:// @TODO Implement $compress
 ./inc/wrapper-functions.php:137:// @TODO Implement $decompress
 ./inc/wrapper-functions.php:514:// @TODO Do some more sanity check here
index 98f19e2..59c06e6 100644 (file)
@@ -42,14 +42,15 @@ if (!defined('__SECURITY')) {
 
 // Handles the XML node 'admin-entry-meta-data'
 function doXmlAdminEntryMetaData ($resource, $attributes) {
-       /*
-        * This node has no attributes by default so it remains just with this
-        * comment.
-        */
+       // There should be no attributes
+       if (count($attributes) > 0) {
+               // Please don't add any attributes to foo-list nodes
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 0 attributes, got ' . count($attributes));
+       } // END - if
 }
 
-// Handles the XML node 'admin-callback-function'
-function doXmlAdminCallbackFunction ($resource, $attributes) {
+// Handles the XML node 'callback-function'
+function doXmlCallbackFunction ($resource, $attributes) {
        // There are two attributes, by default
        if (count($attributes) != 2) {
                // Not the right count
@@ -95,13 +96,14 @@ function doXmlPostDataIdentifyIndex ($resource, $attributes) {
        } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
                // Not valid/verifyable
                debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. TYPE=' . $attributes['TYPE'] . ',VALUE=' . $attributes['VALUE']);
-       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction'])) {
-               // doXmlAdminCallbackFunction is missing
-               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node admin-callback-function not included around this node. Please fix your XML.');
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function not included around this node. Please fix your XML.');
        }
 
        // Add the POST data index for 'id'
-       $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['id_index'] = $attributes['VALUE'];
+       addXmlValueToCallbackAttributes('id_index', $attributes);
+       //$GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['id_index'] = $attributes['VALUE'];
 }
 
 // Handles the XML node 'database-table'
@@ -125,13 +127,14 @@ function doXmlDatabaseTable ($resource, $attributes) {
        } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
                // Not valid/verifyable
                debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. TYPE=' . $attributes['TYPE'] . ',VALUE=' . $attributes['VALUE']);
-       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction'])) {
-               // doXmlAdminCallbackFunction is missing
-               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node admin-callback-function not included around this node. Please fix your XML.');
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function not included around this node. Please fix your XML.');
        }
 
-       // Add the database's name
-       $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['database_table'] = $attributes['VALUE'];
+       // Add the entry to the list
+       addXmlValueToCallbackAttributes('database_table', $attributes);
+       //$GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['database_table'] = $attributes['VALUE'];
 }
 
 // Handles the XML node 'database-column-list'
@@ -143,7 +146,7 @@ function doXmlDatabaseColumnList ($resource, $attributes) {
        } // END - if
 
        // Add an empty list
-       $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['column_list'] = array();
+       $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['column_list'] = array();
 }
 
 // Handles the XML node 'database-column-list-entry'
@@ -167,9 +170,9 @@ function doXmlDatabaseColumnListEntry ($resource, $attributes) {
        } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
                // Not valid/verifyable
                debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. TYPE=' . $attributes['TYPE'] . ',VALUE=' . $attributes['VALUE']);
-       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['column_list'])) {
-               // doXmlAdminCallbackFunction is missing
-               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node admin-callback-function/database-column-list not included around this node. Please fix your XML.');
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['column_list'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function/database-column-list not included around this node. Please fix your XML.');
        }
 
        // Add the entry to the list
@@ -185,7 +188,7 @@ function doXmlCallbackFunctionList ($resource, $attributes) {
        } // END - if
 
        // Add an empty list
-       $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['callback_list'] = array();
+       $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['callback_list'] = array();
 }
 
 // Handles the XML node 'callback-function-list-entry'
@@ -209,9 +212,9 @@ function doXmlCallbackFunctionListEntry ($resource, $attributes) {
        } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
                // Not valid/verifyable
                debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. TYPE=' . $attributes['TYPE'] . ',VALUE=' . $attributes['VALUE']);
-       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['callback_list'])) {
-               // doXmlAdminCallbackFunction is missing
-               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node admin-callback-function/callback-function-list not included around this node. Please fix your XML.');
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['callback_list'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function/callback-function-list not included around this node. Please fix your XML.');
        }
 
        // Add the entry to the list
@@ -227,7 +230,7 @@ function doXmlExtraParameterList ($resource, $attributes) {
        } // END - if
 
        // Add an empty list
-       $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['extra_list'] = array();
+       $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['extra_list'] = array();
 }
 
 // Handles the XML node 'extra-parameter-list-entry'
@@ -251,9 +254,9 @@ function doXmlExtraParameterListEntry ($resource, $attributes) {
        } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
                // Not valid/verifyable
                debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. TYPE=' . $attributes['TYPE'] . ',VALUE=' . $attributes['VALUE']);
-       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['extra_list'])) {
-               // doXmlAdminCallbackFunction is missing
-               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node admin-callback-function/extra-parameter-list not included around this node. Please fix your XML.');
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['extra_list'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function/extra-parameter-list not included around this node. Please fix your XML.');
        }
 
        // Add the entry to the list
@@ -266,7 +269,7 @@ function doXmlExtraParameterMemberList ($resource, $attributes) {
        if (count($attributes) > 0) {
                // Please don't add any attributes to foo-list nodes
                debug_report_bug(__FUNCTION__, __LINE__, 'Expected 0 attributes because this is a foo-list node, got ' . count($attributes));
-       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['extra_list']['member_list'])) {
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['extra_list']['member_list'])) {
                // This list should be created already
                debug_report_bug(__FUNCTION__, __LINE__, 'member_list should be already created.');
        }
@@ -293,9 +296,9 @@ function doXmlExtraParameterMemberListEntry ($resource, $attributes) {
        } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
                // Not valid/verifyable
                debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. TYPE=' . $attributes['TYPE'] . ',VALUE=' . $attributes['VALUE']);
-       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['extra_list']['member_list'])) {
-               // doXmlAdminCallbackFunction is missing
-               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node admin-callback-function/extra-parameter-list/member-list not included around this node. Please fix your XML.');
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['extra_list']['member_list'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function/extra-parameter-list/member-list not included around this node. Please fix your XML.');
        }
 
        // Add the entry to the list
@@ -323,13 +326,13 @@ function doXmlStatusChangeColumn ($resource, $attributes) {
        } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
                // Not valid/verifyable
                debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. TYPE=' . $attributes['TYPE'] . ',VALUE=' . $attributes['VALUE']);
-       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction'])) {
-               // doXmlAdminCallbackFunction is missing
-               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node admin-callback-function not included around this node. Please fix your XML.');
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function not included around this node. Please fix your XML.');
        }
 
        // Add the entry to the list
-       $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['status_list'][$attributes['VALUE']] = array();
+       $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['status_list'][$attributes['VALUE']] = array();
 }
 
 // Handles the XML node 'status-change-list'
@@ -338,9 +341,9 @@ function doXmlStatusChangeList ($resource, $attributes) {
        if (count($attributes) > 0) {
                // Please don't add any attributes to foo-list nodes
                debug_report_bug(__FUNCTION__, __LINE__, 'Expected 0 attributes because this is a foo-list node, got ' . count($attributes));
-       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['status_list'])) {
-               // doXmlAdminCallbackFunction is missing
-               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node admin-callback-function/status-list not included around this node. Please fix your XML.');
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['status_list'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function/status-list not included around this node. Please fix your XML.');
        }
 }
 
@@ -368,9 +371,9 @@ function doXmlStatusChangeListEntry ($resource, $attributes) {
        } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
                // Not valid/verifyable
                debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. TYPE=' . $attributes['TYPE'] . ',VALUE=' . $attributes['VALUE']);
-       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['status_list'])) {
-               // doXmlAdminCallbackFunction is missing
-               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node admin-callback-function/extra-parameter-list/member-list not included around this node. Please fix your XML.');
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['status_list'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function/extra-parameter-list/member-list not included around this node. Please fix your XML.');
        }
 
        // Add the entry to the list
@@ -398,13 +401,14 @@ function doXmlEnableModifyEntries ($resource, $attributes) {
        } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
                // Not valid/verifyable
                debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. TYPE=' . $attributes['TYPE'] . ',VALUE=' . $attributes['VALUE']);
-       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction'])) {
-               // doXmlAdminCallbackFunction is missing
-               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node admin-callback-function not included around this node. Please fix your XML.');
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function not included around this node. Please fix your XML.');
        }
 
-       // Add the entry to the array
-       $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['enable_modify_entries'] = convertStringToBoolean($attributes['VALUE']);
+       // Add the entry to the list
+       addXmlValueToCallbackAttributes('enable_modify_entries', $attributes);
+       //$GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['enable_modify_entries'] = convertStringToBoolean($attributes['VALUE']);
 }
 
 // Handles the XML node 'table-id-column'
@@ -428,13 +432,14 @@ function doXmlTableIdColumn ($resource, $attributes) {
        } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
                // Not valid/verifyable
                debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. TYPE=' . $attributes['TYPE'] . ',VALUE=' . $attributes['VALUE']);
-       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction'])) {
-               // doXmlAdminCallbackFunction is missing
-               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node admin-callback-function not included around this node. Please fix your XML.');
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function not included around this node. Please fix your XML.');
        }
 
        // Add the entry to the array
-       $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['table_id_column'] = $attributes['VALUE'];
+       addXmlValueToCallbackAttributes('table_id_column', $attributes);
+       //$GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['table_id_column'] = $attributes['VALUE'];
 }
 
 // Handles the XML node 'table-userid-column'
@@ -458,13 +463,14 @@ function doXmlTableUseridColumn ($resource, $attributes) {
        } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
                // Not valid/verifyable
                debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. TYPE=' . $attributes['TYPE'] . ',VALUE=' . $attributes['VALUE']);
-       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction'])) {
-               // doXmlAdminCallbackFunction is missing
-               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node admin-callback-function not included around this node. Please fix your XML.');
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function not included around this node. Please fix your XML.');
        }
 
        // Add the entry to the array
-       $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['table_userid_column'] = $attributes['VALUE'];
+       addXmlValueToCallbackAttributes('table_userid_column', $attributes);
+       //$GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['table_userid_column'] = $attributes['VALUE'];
 }
 
 // Handles the XML node 'raw-userid-column-key'
@@ -488,18 +494,386 @@ function doXmlRawUseridColumnKey ($resource, $attributes) {
        } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
                // Not valid/verifyable
                debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. TYPE=' . $attributes['TYPE'] . ',VALUE=' . $attributes['VALUE']);
-       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction'])) {
-               // doXmlAdminCallbackFunction is missing
-               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node admin-callback-function not included around this node. Please fix your XML.');
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function not included around this node. Please fix your XML.');
+       }
+
+       // Add the entry to the array
+       addXmlValueToCallbackAttributes('raw_userid_column_key', $attributes);
+       //$GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['raw_userid_column_key'] = $attributes['VALUE'];
+}
+
+//-----------------------------------------------------------------------------
+//           Call-back functions for listing of data in admin area
+//-----------------------------------------------------------------------------
+
+// Handles the XML node 'admin-list-data'
+function doXmlAdminListData ($resource, $attributes) {
+       // There should be no attributes
+       if (count($attributes) > 0) {
+               // Please don't add any attributes to foo-list nodes
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 0 attributes, got ' . count($attributes));
+       } // END - if
+}
+
+// Handles the XML node 'data-tables'
+function doXmlDataTables ($resource, $attributes) {
+       // There should be no attributes
+       if (count($attributes) > 0) {
+               // Please don't add any attributes to foo-list nodes
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 0 attributes, got ' . count($attributes));
+       } // END - if
+}
+
+// Handles the XML node 'data-table'
+function doXmlDataTable ($resource, $attributes) {
+       // There are three attributes, by default
+       if (count($attributes) != 3) {
+               // Not the right count
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 3 attributes, got ' . count($attributes));
+       } elseif (!isset($attributes['VALUE'])) {
+               // 'VALUE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute VALUE not found.');
+       } elseif (!isset($attributes['TYPE'])) {
+               // 'TYPE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute TYPE not found.');
+       } elseif (!isInvalidXmlType($attributes['TYPE'])) {
+               // No valid type
+               debug_report_bug(__FUNCTION__, __LINE__, 'TYPE is not valid, got: ' . $attributes['TYPE']);
+       } elseif (!isset($attributes['ALIAS'])) {
+               // 'ALIAS' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute ALIAS not found.');
+       } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
+               // Not valid/verifyable
+               debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. VALUE=' . $attributes['VALUE']);
+       } elseif ((trim($attributes['ALIAS']) != '') && (!isXmlValueValid($attributes['TYPE'], $attributes['ALIAS']))) {
+               // Not valid/verifyable
+               debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. ALIAS=' . $attributes['ALIAS']);
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function not included around this node. Please fix your XML.');
+       }
+
+       // Add the entry to the array
+       addXmlValueToCallbackAttributes('data_table', $attributes);
+}
+
+// Handles the XML node 'select-data-from-list'
+function doXmlSelectDataFromList ($resource, $attributes) {
+       // There should be no attributes
+       if (count($attributes) > 0) {
+               // Please don't add any attributes to foo-list nodes
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 0 attributes because this is a foo-list node, got ' . count($attributes));
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['data_table'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function/data-table not included around this node. Please fix your XML.');
+       }
+
+       // Add an empty list
+       $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['data_column_list'] = array();
+}
+
+// Handles the XML node 'select-data-from-list-entry'
+function doXmlSelectDataFromListEntry ($resource, $attributes) {
+       // There are five attributes, by default
+       if (count($attributes) != 5) {
+               // Not the right count
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 5 attributes, got ' . count($attributes));
+       } elseif (!isset($attributes['VALUE'])) {
+               // 'VALUE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute VALUE not found.');
+       } elseif (!isset($attributes['TYPE'])) {
+               // 'TYPE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute TYPE not found.');
+       } elseif (!isInvalidXmlType($attributes['TYPE'])) {
+               // No valid type
+               debug_report_bug(__FUNCTION__, __LINE__, 'TYPE is not valid, got: ' . $attributes['TYPE']);
+       } elseif (!isset($attributes['ALIAS'])) {
+               // 'ALIAS' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute ALIAS not found.');
+       } elseif (!isset($attributes['FUNCTION'])) {
+               // 'FUNCTION' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute FUNCTION not found.');
+       } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
+               // 'VALUE' not valid/verifyable
+               debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. VALUE=' . $attributes['VALUE']);
+       } elseif ((trim($attributes['ALIAS']) != '') && (!isXmlValueValid($attributes['TYPE'], $attributes['ALIAS']))) {
+               // 'ALIAS' not valid/verifyable
+               debug_report_bug(__FUNCTION__, __LINE__, 'Attribute ALIAS does not validate. ALIAS=' . $attributes['ALIAS']);
+       } elseif ((trim($attributes['FUNCTION']) != '') && (!isXmlValueValid($attributes['TYPE'], $attributes['FUNCTION']))) {
+               // 'FUNCTION' not valid/verifyable
+               debug_report_bug(__FUNCTION__, __LINE__, 'Attribute FUNCTION does not validate. FUNCTION=' . $attributes['FUNCTION']);
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['data_column_list'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function/select-data-from-list not included around this node. Please fix your XML.');
+       }
+
+       // Add the entry to the array
+       addXmlValueToCallbackAttributes('data_column_list', $attributes);
+}
+
+// Handles the XML node 'where-select-from-list'
+function doXmlWhereSelectFromList ($resource, $attributes) {
+       // There should be no attributes
+       if (count($attributes) > 0) {
+               // Please don't add any attributes to foo-list nodes
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 0 attributes because this is a foo-list node, got ' . count($attributes));
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['data_table'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function/data-table not included around this node. Please fix your XML.');
+       }
+
+       // Add an empty list
+       $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['where_select_list'] = array();
+}
+
+// Handles the XML node 'order-by-list'
+function doXmlOrderByList ($resource, $attributes) {
+       // There should be no attributes
+       if (count($attributes) > 0) {
+               // Please don't add any attributes to foo-list nodes
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 0 attributes because this is a foo-list node, got ' . count($attributes));
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['data_table'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function/data-table not included around this node. Please fix your XML.');
+       }
+
+       // Add an empty list
+       $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['order_by_list'] = array();
+}
+
+// Handles the XML node 'order-by-list-entry'
+function doXmlOrderByListEntry ($resource, $attributes) {
+       // There are four attributes, by default
+       if (count($attributes) != 4) {
+               // Not the right count
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 5 attributes, got ' . count($attributes));
+       } elseif (!isset($attributes['ORDER'])) {
+               // 'ORDER' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute ORDER not found.');
+       } elseif (!isset($attributes['TYPE'])) {
+               // 'TYPE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute TYPE not found.');
+       } elseif (!isInvalidXmlType($attributes['TYPE'])) {
+               // No valid type
+               debug_report_bug(__FUNCTION__, __LINE__, 'TYPE is not valid, got: ' . $attributes['TYPE']);
+       } elseif (!isset($attributes['TABLE'])) {
+               // 'TABLE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute TABLE not found.');
+       } elseif (!isset($attributes['VALUE'])) {
+               // 'VALUE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute VALUE not found.');
+       } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['ORDER'])) {
+               // 'ORDER' not valid/verifyable
+               debug_report_bug(__FUNCTION__, __LINE__, 'Attribute ORDER does not validate. ORDER=' . $attributes['ORDER']);
+       } elseif ((trim($attributes['TABLE']) != '') && (!isXmlValueValid($attributes['TYPE'], $attributes['TABLE']))) {
+               // 'TABLE' not valid/verifyable
+               debug_report_bug(__FUNCTION__, __LINE__, 'Attribute TABLE does not validate. TABLE=' . $attributes['TABLE']);
+       } elseif ((trim($attributes['VALUE']) != '') && (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE']))) {
+               // 'VALUE' not valid/verifyable
+               debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. VALUE=' . $attributes['VALUE']);
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['data_column_list'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function/data-column-list not included around this node. Please fix your XML.');
+       }
+
+       // Add the entry to the array
+       addXmlValueToCallbackAttributes('order_by_list', $attributes);
+}
+
+// Handles the XML node 'list-template'
+function doXmlListTemplate ($resource, $attributes) {
+       // There are two attributes, by default
+       if (count($attributes) != 2) {
+               // Not the right count
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 3 attributes, got ' . count($attributes));
+       } elseif (!isset($attributes['VALUE'])) {
+               // 'VALUE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute VALUE not found.');
+       } elseif (!isset($attributes['TYPE'])) {
+               // 'TYPE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute TYPE not found.');
+       } elseif (!isInvalidXmlType($attributes['TYPE'])) {
+               // No valid type
+               debug_report_bug(__FUNCTION__, __LINE__, 'TYPE is not valid, got: ' . $attributes['TYPE']);
+       } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
+               // Not valid/verifyable
+               debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. VALUE=' . $attributes['VALUE']);
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function not included around this node. Please fix your XML.');
        }
 
        // Add the entry to the array
-       $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction']['raw_userid_column_key'] = $attributes['VALUE'];
+       addXmlValueToCallbackAttributes('list_template', $attributes);
+}
+
+// Handles the XML node 'list-row-template'
+function doXmlListRowTemplate ($resource, $attributes) {
+       // There are two attributes, by default
+       if (count($attributes) != 2) {
+               // Not the right count
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 3 attributes, got ' . count($attributes));
+       } elseif (!isset($attributes['VALUE'])) {
+               // 'VALUE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute VALUE not found.');
+       } elseif (!isset($attributes['TYPE'])) {
+               // 'TYPE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute TYPE not found.');
+       } elseif (!isInvalidXmlType($attributes['TYPE'])) {
+               // No valid type
+               debug_report_bug(__FUNCTION__, __LINE__, 'TYPE is not valid, got: ' . $attributes['TYPE']);
+       } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
+               // Not valid/verifyable
+               debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. VALUE=' . $attributes['VALUE']);
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function not included around this node. Please fix your XML.');
+       }
+
+       // Add the entry to the array
+       addXmlValueToCallbackAttributes('list_row_template', $attributes);
+}
+
+// Handles the XML node 'column-callback-list'
+function doXmlColumnCallbackList ($resource, $attributes) {
+       // There should be no attributes
+       if (count($attributes) > 0) {
+               // Please don't add any attributes to foo-list nodes
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 0 attributes because this is a foo-list node, got ' . count($attributes));
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['data_table'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function/data-table not included around this node. Please fix your XML.');
+       }
+
+       // Add an empty list
+       $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['column_callback_list'] = array();
 }
 
-// ----------------------------------------------------------------------------
-//                                XML type validation
-// ----------------------------------------------------------------------------
+// Handles the XML node 'column-callback-list-entry'
+function doXmlColumnCallbackListEntry ($resource, $attributes) {
+       // There should be no attributes
+       if (count($attributes) > 0) {
+               // Please don't add any attributes to foo-list nodes
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 0 attributes because this is a foo-list node, got ' . count($attributes));
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['column_callback_list'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function/column-callback not included around this node. Please fix your XML.');
+       }
+}
+
+// Handles the XML node 'column-callback-data'
+function doXmlColumnCallbackData ($resource, $attributes) {
+       // There are three attributes, by default
+       if (count($attributes) != 3) {
+               // Not the right count
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 3 attributes, got ' . count($attributes));
+       } elseif (!isset($attributes['VALUE'])) {
+               // 'VALUE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute VALUE not found.');
+       } elseif (!isset($attributes['TYPE'])) {
+               // 'TYPE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute TYPE not found.');
+       } elseif (!isset($attributes['CALLBACK'])) {
+               // 'CALLBACK' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute CALLBACK not found.');
+       } elseif (!isInvalidXmlType($attributes['TYPE'])) {
+               // No valid type
+               debug_report_bug(__FUNCTION__, __LINE__, 'TYPE is not valid, got: ' . $attributes['TYPE']);
+       } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
+               // Not valid/verifyable
+               debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. VALUE=' . $attributes['VALUE']);
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function not included around this node. Please fix your XML.');
+       } elseif ((trim($attributes['CALLBACK']) != '') && (!isXmlValueValid($attributes['TYPE'], $attributes['CALLBACK']))) {
+               // 'CALLBACK' not valid/verifyable
+               debug_report_bug(__FUNCTION__, __LINE__, 'Attribute CALLBACK does not validate. CALLBACK=' . $attributes['CALLBACK']);
+       }
+
+       // Add the entry to the array
+       addXmlValueToCallbackAttributes('column_callback_list', $attributes);
+}
+
+// Handles the XML node 'callback-extra-parameter-list'
+function doXmlCallbackExtraParameterList ($resource, $attributes) {
+       // There should be no attributes
+       if (count($attributes) > 0) {
+               // Please don't add any attributes to foo-list nodes
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 1 attributes because this is a named foo-list node, got ' . count($attributes));
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['column_callback_list'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function/column-callback-list not included around this node. Please fix your XML.');
+       } elseif (isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['__EXTRA_PARAMETER'])) {
+               // Abort silently here, no one wants to kill this array
+               return;
+       }
+
+       // Add an empty list
+       $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['__EXTRA_PARAMETER'] = array();
+}
+
+// Handles the XML node 'callback-extra-parameter-list-entry'
+function doXmlCallbackExtraParameterListEntry ($resource, $attributes) {
+       // There are three attributes, by default
+       if (count($attributes) != 3) {
+               // Not the right count
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 5 attributes, got ' . count($attributes));
+       } elseif (!isset($attributes['COLUMN'])) {
+               // 'COLUMN' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute COLUMN not found.');
+       } elseif (!isset($attributes['TYPE'])) {
+               // 'TYPE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute TYPE not found.');
+       } elseif (!isInvalidXmlType($attributes['TYPE'])) {
+               // No valid type
+               debug_report_bug(__FUNCTION__, __LINE__, 'TYPE is not valid, got: ' . $attributes['TYPE']);
+       } elseif (!isset($attributes['VALUE'])) {
+               // 'VALUE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute VALUE not found.');
+       } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
+               // 'VALUE' not valid/verifyable
+               debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. VALUE=' . $attributes['VALUE']);
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction']['__EXTRA_PARAMETER'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function/__EXTRA_PARAMETER not included around this node. Please fix your XML.');
+       }
+
+       // Add the entry to the array
+       addXmlValueToCallbackAttributes('__EXTRA_PARAMETER', $attributes);
+}
+
+// Handles the XML node 'no-entry-found-message'
+function doXmlNoEntryFoundMessage ($resource, $attributes) {
+       // There are two attributes, by default
+       if (count($attributes) != 2) {
+               // Not the right count
+               debug_report_bug(__FUNCTION__, __LINE__, 'Expected 3 attributes, got ' . count($attributes));
+       } elseif (!isset($attributes['VALUE'])) {
+               // 'VALUE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute VALUE not found.');
+       } elseif (!isset($attributes['TYPE'])) {
+               // 'TYPE' not found
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required attribute TYPE not found.');
+       } elseif (!isInvalidXmlType($attributes['TYPE'])) {
+               // No valid type
+               debug_report_bug(__FUNCTION__, __LINE__, 'TYPE is not valid, got: ' . $attributes['TYPE']);
+       } elseif (!isXmlValueValid($attributes['TYPE'], $attributes['VALUE'])) {
+               // Not valid/verifyable
+               debug_report_bug(__FUNCTION__, __LINE__, 'Attribute VALUE does not validate. VALUE=' . $attributes['VALUE']);
+       } elseif (!isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'])) {
+               // doXmlCallbackFunction is missing
+               debug_report_bug(__FUNCTION__, __LINE__, 'Required XML node callback-function not included around this node. Please fix your XML.');
+       }
+
+       // Add the entry to the array
+       addXmlValueToCallbackAttributes('no_entry_message_id', $attributes);
+}
+
+//-----------------------------------------------------------------------------
+//                              XML type validation
+//-----------------------------------------------------------------------------
 
 // Checks for string without any added extra data
 function isXmlTypeString ($value) {
@@ -522,60 +896,103 @@ function isXmlTypeBool ($value) {
        return (($value == 'true') || ($value == 'false'));
 }
 
-// ----------------------------------------------------------------------------
+// Check for integer type
+function isXmlTypeInt ($value) {
+       // Trim value
+       $value = trim($value);
+
+       // This value is always a string
+       return (bigintval($value) == $value);
+}
+
+//-----------------------------------------------------------------------------
 //                               Private XML functions
-// ----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 
 // Adds given attribut to element
 function addXmlValueToCallbackAttributes ($element, $attributes, $extraKey = '', $key = '') {
+       // What do we need to add?
+       /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',extraKey=' . $extraKey . ',key=' . $key . ' - ENTERED!');
        if ($attributes['TYPE'] == 'array') {
                // Another nested array
-               /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'TYPE=ARRAY, element=' . $element);
-               $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction'][$element][$attributes['VALUE'] . '_list'] = array();
+               /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'TYPE=ARRAY, element=' . $element);
+               $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'][$element][$attributes['VALUE'] . '_list'] = array();
        } elseif (!empty($extraKey)) {
                // Is it bool?
-               if ($attributes['TYPE'] == 'bool') {
+               if (($attributes['TYPE'] == 'bool') && (isset($attributes['VALUE']))) {
                        // Then convert VALUE
                        $attributes['VALUE'] = convertStringToBoolean($attributes['VALUE']);
                } // END - if
 
                // Sub-array (one level only)
-               /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',extraKey=' . $extraKey . ',TYPE='.$attributes['TYPE'].',VALUE[' . gettype($attributes['VALUE']) . ']=' . $attributes['VALUE']);
+               /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',extraKey=' . $extraKey . ',TYPE=' . $attributes['TYPE'] . ' - ANALYSING...');
                if (trim($attributes['NAME']) == '') {
                        // Numerical index
-                       /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',extraKey=' . $extraKey . ',TYPE='.$attributes['TYPE'].',VALUE[' . gettype($attributes['VALUE']) . ']=' . $attributes['VALUE'] . ' - NUMERICAL!');
-                       $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction'][$element][$extraKey][] = $attributes['VALUE'];
+                       /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',extraKey=' . $extraKey . ',TYPE=' . $attributes['TYPE'].',VALUE[' . gettype($attributes['VALUE']) . ']=' . $attributes['VALUE'] . ' - NUMERICAL!');
+                       $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'][$element][$extraKey][] = $attributes['VALUE'];
                } elseif (!empty($key)) {
                        // Use from $key
-                       /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',extraKey=' . $extraKey . ',TYPE='.$attributes['TYPE'].',VALUE[' . gettype($attributes['VALUE']) . ']=' . $attributes['VALUE'] . ' - KEY! (key=' . $attributes[$key] . ')');
-                       $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction'][$element][$extraKey][$attributes[$key]] = $attributes['VALUE'];
+                       /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',extraKey=' . $extraKey . ',TYPE=' . $attributes['TYPE'].',VALUE[' . gettype($attributes['VALUE']) . ']=' . $attributes['VALUE'] . ' - KEY! (key=' . $attributes[$key] . ')');
+                       $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'][$element][$extraKey][$attributes[$key]] = $attributes['VALUE'];
                } else {
                        // Use from NAME
-                       /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',extraKey=' . $extraKey . ',TYPE='.$attributes['TYPE'].',VALUE[' . gettype($attributes['VALUE']) . ']=' . $attributes['VALUE'] . ' - NAME! (name=' . $attributes['NAME'] . ')');
-                       $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction'][$element][$extraKey][$attributes['NAME']] = $attributes['VALUE'];
+                       /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',extraKey=' . $extraKey . ',TYPE=' . $attributes['TYPE'].',VALUE[' . gettype($attributes['VALUE']) . ']=' . $attributes['VALUE'] . ' - NAME! (NAME=' . $attributes['NAME'] . ')');
+                       $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'][$element][$extraKey][$attributes['NAME']] = $attributes['VALUE'];
                }
-       } elseif (trim($attributes['NAME']) == '') {
+       } elseif ((isset($attributes['FUNCTION'])) && (isset($attributes['ALIAS']))) {
+               /*
+                * ALIAS and FUNCTION detected? This may happen with SQL queries
+                * like: UNIX_TIMESTAMP(`foo_timestamp`) AS `foo_timestamp`
+                */
+               // Init array
+               $array =  array(
+                       'column'   => trim($attributes['VALUE']),
+                       'alias'    => trim($attributes['ALIAS']),
+                       'function' => trim($attributes['FUNCTION']),
+                       'table'    => trim($attributes['TABLE'])
+               );
+
+               // Add the entry
+               /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',extraKey=' . $extraKey . ',TYPE=' . $attributes['TYPE'].',ALIAS[' . gettype($attributes['ALIAS']) . ']=' . $attributes['ALIAS'] . ',FUNCTION[' . gettype($attributes['FUNCTION']) . ']=' . $attributes['FUNCTION'] . ' - FUNCTION! (VALUE=' . $attributes['VALUE'] . ')');
+               $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'][$element][] = $array;
+       } elseif (isset($attributes['CALLBACK'])) {
+               // CALLBACK/VALUE detected
+               /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',extraKey=' . $extraKey . ',TYPE=' . $attributes['TYPE'].',CALLBACK[' . gettype($attributes['CALLBACK']) . ']=' . $attributes['CALLBACK'] . ' - CALLBACK! (VALUE=' . $attributes['VALUE'] . ')');
+               $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'][$element][$attributes['VALUE']] = $attributes['CALLBACK'];
+       } elseif (isset($attributes['ORDER'])) {
+               // ORDER/TABLE detected
+               /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',extraKey=' . $extraKey . ',TYPE=' . $attributes['TYPE'].',ORDER[' . gettype($attributes['ORDER']) . ']=' . $attributes['ORDER'] . ' - ORDER! (VALUE=' . $attributes['VALUE'] . ')');
+               $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'][$element][$attributes['ORDER']][$attributes['TABLE']] = $attributes['VALUE'];
+       } elseif (isset($attributes['COLUMN'])) {
+               // COLUMN/VALUE detected
+               /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',VALUE[' . gettype($attributes['VALUE']) . ']=' . $attributes['VALUE'] . ',COLUMN[' . gettype($attributes['COLUMN']) . ']=' . $attributes['COLUMN'] . ' - COLUMN!');
+               $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'][$element][$attributes['COLUMN']][] = $attributes['VALUE'];
+       } elseif ((!isset($attributes['NAME'])) || (trim($attributes['NAME']) == '')) {
                // Numerical index
-               /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',VALUE[' . gettype($attributes['VALUE']) . ']=' . $attributes['VALUE']);
-               $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction'][$element][] = $attributes['VALUE'];
-       } elseif (isset($GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction'][$element][$attributes['NAME']])) {
+               /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',VALUE[' . gettype($attributes['VALUE']) . ']=' . $attributes['VALUE'] . ' - NUMERICAL!');
+               $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'][$element][] = $attributes['VALUE'];
+       } elseif (isset($GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'][$element][$attributes['NAME']])) {
                // Already created
-               debug_report_bug(__FUNCTION__, __LINE__, 'NAME=' . $attributes['NAME'] . ' already addded to ' . $element . '.');
+               debug_report_bug(__FUNCTION__, __LINE__, 'NAME=' . $attributes['NAME'] . ' already addded to ' . $element . ' attributes=<pre>' . print_r($attributes, true) . '</pre>');
        } else {
                // Use from NAME
-               /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',NAME=' . $attributes['NAME'] . ',VALUE[' . gettype($attributes['VALUE']) . ']=' . $attributes['VALUE']);
-               $GLOBALS['__XML_ARGUMENTS']['doXmlAdminCallbackFunction'][$element][$attributes['NAME']] = $attributes['VALUE'];
+               /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',NAME=' . $attributes['NAME'] . ',VALUE[' . gettype($attributes['VALUE']) . ']=' . $attributes['VALUE'] . ' - NAME!');
+               $GLOBALS['__XML_ARGUMENTS']['doXmlCallbackFunction'][$element][$attributes['NAME']] = $attributes['VALUE'];
        }
+       /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'element=' . $element . ',extraKey=' . $extraKey . ',key=' . $key . ' - EXIT!');
 }
 
-// ----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 //                            Execute call-back functions
-// ----------------------------------------------------------------------------
-
-// Execute function for doXmlAdminCallbackFunction()
-function doXmlAdminCallbackFunctionExecute ($function, $args) {
-       // Prepare 'id_index'
-       $args['id_index'] = postRequestParameter($args['id_index']);
+//-----------------------------------------------------------------------------
+
+// Execute function for doXmlCallbackFunction()
+function doXmlCallbackFunctionExecute ($function, $args) {
+       // Is 'id_index' set and form sent?
+       if ((isset($args['id_index'])) && (isFormSent())) {
+               // Prepare 'id_index'
+               $args['id_index'] = postRequestParameter($args['id_index']);
+       } // END - if
 
        // Just call it
        //* DEBUG: */ die('<pre>'.print_r($args, true).'</pre>');
index 6a89335..e045b45 100644 (file)
@@ -274,6 +274,8 @@ function updateOldConfigFile () {
 function updateConfiguration ($entries, $values, $updateMode='', $config = '0') {
        // Do not update config in CSS mode
        if ((isCssOutputMode()) || (isRawOutputMode()) || (isInstallationPhase())) {
+               // This logger line may be very noisy
+               /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Not updating configuration. entries[]=' . gettype($entries) . ',values[]=' . gettype($values) . ',updateMode=' . $updateMode . ',config=' . $config . ',isCssOutputMode()=' . intval(isCssOutputMode()) . ',isRawOutputMode()=' . intval(isRawOutputMode()) . 'isInstallationPhase()=' . intval(isInstallationPhase()));
                return;
        } // END - if
 
@@ -350,7 +352,7 @@ function updateConfiguration ($entries, $values, $updateMode='', $config = '0')
 
 // Filter for loading configuration
 function FILTER_LOAD_CONFIGURATION ($no = '0') {
-       // Is the value null, fix it :(
+       // Is the value null, it comes from the 'init' filter chain
        if (is_null($no)) {
                $no = '0';
        } // END - if
index 8d83be5..b32f46c 100644 (file)
@@ -53,7 +53,10 @@ if (!defined('__SECURITY')) {
 if ((isSendProfileUpdateEnabled()) && (getProfileUpdate() > 0) && (getResendProfileUpdate() > 0)) {
        // Load personal data
        $result = SQL_QUERY("SELECT
-       `userid`, `email`, `last_update`, `joined`
+       `userid`,
+       `email`,
+       `last_update`,
+       `joined`
 FROM
        `{?_MYSQL_PREFIX?}_user_data`
 WHERE
@@ -76,14 +79,14 @@ ORDER BY
                // We need to send-out notifications...
                while ($content = SQL_FETCHARRAY($result)) {
                        // Translate timestamp
-                       $content['joined'] = generateDateTime($content['joined'], 0);
+                       $content['joined'] = generateDateTime($content['joined'], '0');
 
                        if (round($content['last_update']) == '0') {
                                // Has never changed his accont
                                $content['last_update'] = '{--MEMBER_PROFILE_NEVER_CHANGED--}';
                        } else {
                                // Has changed his account
-                               $content['last_update'] = generateDateTime($content['last_update'], 0);
+                               $content['last_update'] = generateDateTime($content['last_update'], '0');
                        }
 
                        // Load email template and send mail away
index 22a2d52..44e4cb0 100644 (file)
@@ -120,9 +120,9 @@ ORDER BY
        registerFilter('pre_page_header', 'LOAD_PAGE_HEADER');
 
        // Page headers - post-filter (normally, you don't want to register here)
-       // ------------------- LAST FILTER FOR THIS CHAIN! ------------------------
+       //-------------------- LAST FILTER FOR THIS CHAIN! ------------------------
        registerFilter('post_page_header', 'FINISH_PAGE_HEADER');
-       // ------------------- LAST FILTER FOR THIS CHAIN! ------------------------
+       //-------------------- LAST FILTER FOR THIS CHAIN! ------------------------
 
        // 'You are here' navigation - post filter
        registerFilter('post_youhere_line', 'CALL_HANDLER_LOGIN_FAILTURES');
index 2c84b62..a5d7e65 100644 (file)
@@ -1162,7 +1162,7 @@ addMessages(array(
        'ADMIN_CONFIG_GUEST_STATS_INACTIVE_NOTE' => "Deaktiviert die Gast-Statistiken komplett.",
 
        // XML related strings
-       'XML_TEMPLATE_404' => "XML-Template <span class=\"data\">%s</span nicht gefunden.",
+       'XML_TEMPLATE_404' => "XML-Template <span class=\"data\">%s</span> nicht gefunden.",
 
        // Admin actions - submit buttons
        'ADMIN_ACTION_EDIT_SUBMIT' => "Bearbeiten",
index c1987fb..62de1ca 100644 (file)
@@ -640,9 +640,9 @@ function getAdminLastFailure ($adminId) {
        return $data['last_failure'];
 }
 
-// ---------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 //                             Wrapper functions
-// ---------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 
 // Wrapper function to check wether expert setting warning is enabled
 function isAdminsExpertWarningEnabled () {
index b362283..953a5ff 100644 (file)
@@ -67,9 +67,9 @@ function addPointsBeg ($userid, $points) {
        return $added;
 }
 
-// ----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 //                       Wrapper functions for ext-beg
-// ----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 
 // "Getter" for beg_new_member_notify
 function getBegNewMemberNotify () {
index fab47f8..94148e2 100644 (file)
@@ -148,9 +148,9 @@ function getDoublerTotalPointsLeft() {
        return $points;
 }
 
-// ----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 //                      Wrapper functions for ext-doubler
-// ----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 
 // "Getter" for doubler_userid
 function getDoublerUserid () {
index 7a6fb06..ea1ddae 100644 (file)
@@ -65,9 +65,9 @@ function addOrderSelectionOptions ($default) {
        return $OUT;
 }
 
-// ----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 //                Wrapper functions for configuration entries
-// ----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 
 // Getter for 'order_multi_page' config entry
 function getOrderMultiPage () {
index 8cf8af7..97b197f 100644 (file)
@@ -40,9 +40,9 @@ if (!defined('__SECURITY')) {
        die();
 } // END - if
 
-// ----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 //                             Wrapper functions
-// ----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 
 // Getter for profile_update
 function getProfileUpdate () {
index 6e10e27..b3aea55 100644 (file)
@@ -40,9 +40,9 @@ if (!defined('__SECURITY')) {
        die();
 } // END - if
 
-// -----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
 //                               Admin functions
-// -----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
 //
 // Admin has added an URL with given user id and so on
 function SURFBAR_ADMIN_ADD_URL ($url, $limit, $reload) {
@@ -153,9 +153,9 @@ function SURFBAR_ADMIN_REJECT_URL_IDS ($IDs) {
 }
 
 //
-// -----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
 //                               Member functions
-// -----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
 //
 // Member has added an URL
 function SURFBAR_MEMBER_ADD_URL ($url, $limit) {
@@ -286,9 +286,9 @@ function SURFBAR_VALIDATE_MEMBER_ACTION_STATUS ($action, $status) {
 }
 
 //
-// -----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
 //                               Member actions
-// -----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
 //
 // Retreat a booked URL
 function SURFBAR_MEMBER_RETREAT_ACTION ($urlData) {
@@ -439,9 +439,9 @@ function SURFBAR_MEMBER_EXECUTE_DELETE_ACTION ($urlData) {
        return true;
 }
 //
-// -----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
 //                           Self-maintenance functions
-// -----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
 //
 // Main function
 function SURFBAR_HANDLE_SELF_MAINTENANCE () {
@@ -499,9 +499,9 @@ function SURFBAR_HANDLE_LOW_POINTS () {
 }
 
 //
-// -----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
 //                               Generic functions
-// -----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
 //
 
 // Looks up by an URL
@@ -1772,9 +1772,9 @@ LIMIT 1",
        return $nextId;
 }
 
-// ----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 // Wrapper function
-// ----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 
 // "Getter" for surfbar_dynamic_percent
 function getSurfbarDynamicPercent () {
@@ -1836,10 +1836,10 @@ function getSurfbarPaymentModel () {
        return $GLOBALS[__FUNCTION__];
 }
 
-// -----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
 // PLEASE DO NOT ADD ANY OTHER FUNCTIONS BELOW THIS LINE IF THEY DON'T "WRAP"
 // THE $GLOBALS['surfbar_cache'] ARRAY!
-// -----------------------------------------------------------------------------
+//------------------------------------------------------------------------------
 
 // Initializes the surfbar
 function SURFBAR_INIT () {
index ea23ae7..b3ddbd6 100644 (file)
@@ -80,9 +80,9 @@ function autoPurgeTransfers ($max, $age) {
        } // END - if
 }
 
-// ---------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 //                              Wrapper functions
-// ---------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 
 // Wrapper function for transfer_code
 function getTransferCode () {
index db99fbd..fb8c57c 100644 (file)
@@ -400,9 +400,9 @@ function WERNIS_ADD_WITHDRAW_FEE ($points) {
        return $points;
 }
 
-// ---------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 //                             Wrapper functions
-// ---------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 
 // Wrapper function for 'wernis_refid'
 function getWernisRefid () {
index 02f1531..db9353b 100644 (file)
@@ -1115,6 +1115,120 @@ function adminUndeleteEntriesConfirm ($IDs, $table, $columns=array(), $filterFun
        } // END - if
 }
 
+// List all given rows (callback function from XML)
+function adminListEntries ($tableTemplate, $rowTemplate, $tableName, $columns, $whereColumns, $orderByColumns, $callbackColumns, $extraParameters, $noEntryMessageId) {
+       // Verify that tableName and columns are not empty
+       if (count($tableName) != 1) {
+               // No tableName specified
+               debug_report_bug(__FUNCTION__, __LINE__, 'tableName is not given. Please fix your XML. tableTemplate=' . $tableTemplate . ',rowTemplate=' . $rowTemplate);
+       } elseif (count($columns) == 0) {
+               // No columns specified
+               debug_report_bug(__FUNCTION__, __LINE__, 'columns is not given. Please fix your XML. tableTemplate=' . $tableTemplate . ',rowTemplate=' . $rowTemplate . ',tableName[0]=' . $tableName[0]);
+       }
+
+       // This is the minimum query, so at least columns and tableName must have entries
+       $SQL = 'SELECT ';
+       foreach ($columns as $columnArray) {
+               // Init SQL part
+               $sqlPart = '';
+               // Do we have a table/alias
+               if (!empty($columnArray['table'])) {
+                       // Pre-add it
+                       $sqlPart .= $columnArray['table'] . '.';
+               } // END - if
+
+               // Add column
+               $sqlPart .= '`' . $columnArray['column'] . '`';
+
+               // Is a function and alias set?
+               if ((!empty($columnArray['function'])) && (!empty($columnArray['alias']))) {
+                       // Add both
+                       $sqlPart = $columnArray['function'] . '(' . $sqlPart . ') AS `' . $columnArray['alias'] . '`';
+               } // END - if
+
+               // Add finished SQL part to the query
+               $SQL .= $sqlPart . ',';
+       } // END - foreach
+
+       // Remove last commata and add FROM statement
+       $SQL = substr($SQL, 0, -1) . ' FROM `{?_MYSQL_PREFIX?}_' . $tableName[0] . '`';
+
+       // Do we have entries from whereColumns to add?
+       if (count($whereColumns) > 0) {
+               // Then add these as well
+               // @TODO WHERE is not yet supported
+               debug_report_bug(__FUNCTION__, __LINE__, 'Unfinished area, please report your XML to the forums or bug tracker. tableTemplate=' . $tableTemplate . ',rowTemplate=' . $rowTemplate . ',tableName[0]=' . $tableName[0]);
+       } // END - if
+
+       // Do we have entries from orderByColumns to add?
+       if (count($orderByColumns) > 0) {
+               // Add them as well
+               $SQL .= ' ORDER BY ';
+               foreach ($orderByColumns as $orderByColumn=>$array) {
+                       // Get keys (table/alias) and values (sorting itself)
+                       $table   = trim(implode('', array_keys($array)));
+                       $sorting = trim(implode('', array_keys($array)));
+
+                       // table/alias can be omitted
+                       if (!empty($table)) {
+                               // table/alias is given
+                               $SQL .= $table . '.';
+                       } // END - if
+
+                       // Add order-by column
+                       $SQL .= '`' . $orderByColumn . '` ' . $sorting . ',';
+               } // END - foreach
+
+               // Remove last column
+               $SQL = substr($SQL, 0, -1);
+       } // END - if
+
+       // Now handle all over to the inner function which will execute the listing
+       doAdminListEntries($SQL, $tableTemplate, $rowTemplate, $callbackColumns, $extraParameters, $noEntryMessageId);
+}
+
+// Do the listing of entries
+function doAdminListEntries($SQL, $tableTemplate, $rowTemplate, $callbackColumns, $extraParameters, $noEntryMessageId) {
+       // Run the SQL query
+       $result = SQL_QUERY($SQL, __FUNCTION__, __LINE__);
+
+       // Do we have some URLs left?
+       if (!SQL_HASZERONUMS($result)) {
+               // List all URLs
+               $OUT = '';
+               while ($content = SQL_FETCHARRAY($result)) {
+                       // "Translate" content
+                       foreach ($callbackColumns as $column=>$callbackFunction) {
+                               // Fill the callback arguments
+                               $args = array($content[$column]);
+
+                               // Do we have more to add?
+                               if (isset($extraParameters[$column])) {
+                                       // Add them as well
+                                       merge_array($args, $extraParameters[$column]);
+                               } // END - if
+
+                               // Call the callback-function
+                               //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'callbackFunction=' . $callbackFunction . ',args=<pre>'.print_r($args, true).'</pre>');
+                               // @TODO If we can rewrite the EL sub-system to support more than one parameter, this call_user_func_array() can be avoided
+                               $content[$column] = call_user_func_array($callbackFunction, $args);
+                       } // END - foreach
+
+                       // Load row template
+                       $OUT .= loadTemplate(trim($rowTemplate[0]), true, $content);
+               } // END - while
+
+               // Load main template
+               loadTemplate(trim($tableTemplate[0]), false, $OUT);
+       } else {
+               // No URLs in surfbar
+               displayMessage('{--' .$noEntryMessageId . '--}');
+       }
+
+       // Free result
+       SQL_FREERESULT($result);
+}
+
 // Checks proxy settins by fetching check-updates3.php from www.mxchange.org
 function adminTestProxySettings ($settingsArray) {
        // Set temporary the new settings
index aed7a27..ad6c741 100644 (file)
@@ -101,42 +101,7 @@ if ($show === false) {
 } // END - if
 
 // List all URLs
-$result = SQL_QUERY("SELECT
-       `url_id`,
-       `url_userid`,
-       `url`,
-       `url_views_total`,
-       `url_status`,
-       UNIX_TIMESTAMP(`url_registered`) AS `url_registered`,
-       UNIX_TIMESTAMP(`url_last_locked`) AS `url_last_locked`,
-       `url_lock_reason`
-FROM
-       `{?_MYSQL_PREFIX?}_surfbar_urls`
-ORDER BY
-       `url_id` ASC", __FILE__, __LINE__);
-
-// Do we have some URLs left?
-if (!SQL_HASZERONUMS($result)) {
-       // List all URLs
-       $OUT = '';
-       while ($content = SQL_FETCHARRAY($result)) {
-               // "Translate" content
-               $content['url_registered']  = generateDateTime($content['url_registered'], '2');
-               $content['url_last_locked'] = generateDateTime($content['url_last_locked'], '2');
-
-               // Load row template
-               $OUT .= loadTemplate('admin_list_surfbar_urls_row', true, $content);
-       } // END - while
-
-       // Load main template
-       loadTemplate('admin_list_surfbar_urls', false, $OUT);
-} else {
-       // No URLs in surfbar
-       displayMessage('{--ADMIN_SURFBAR_NO_URLS_FOUND--}');
-}
-
-// Free result
-SQL_FREERESULT($result);
+showEntriesByXmlCallback('admin_list_surfbar_urls');
 
 // [EOF]
 ?>
index da8d167..611d1b1 100644 (file)
@@ -262,8 +262,13 @@ function outputRawCode ($htmlCode) {
 
 // Load a template file and return it's content (only it's name; do not use ' or ")
 function loadTemplate ($template, $return = false, $content = array(), $compileCode = true) {
-       // @TODO Remove this sanity-check if all is fine
-       if (!is_bool($return)) debug_report_bug(__FUNCTION__, __LINE__, 'return is not bool (' . gettype($return) . ')');
+       if (!is_bool($return)) {
+               // @TODO Remove this sanity-check if all is fine
+               debug_report_bug(__FUNCTION__, __LINE__, 'return[] is not bool (' . gettype($return) . ')');
+       } elseif (!is_string($template)) {
+               // $template has to be string
+               debug_report_bug(__FUNCTION__, __LINE__, 'template[] is not string (' . gettype($template) . ')');
+       }
 
        // Set current template
        $GLOBALS['current_template'] = $template;
index 564ee85..a89c49a 100644 (file)
@@ -2537,6 +2537,26 @@ function convertCommaToDotInPostDataArray ($postEntries) {
        } // END - foreach
 }
 
+/**
+ * Parses a string into a US formated float variable, taken from user comments
+ * from PHP documentation website.
+ *
+ * @param      $floatString    A string holding a float expression
+ * @return     $float                  Corresponding float variable
+ * @author     chris<at>georgakopoulos<dot>com
+ * @link       http://de.php.net/manual/en/function.floatval.php#92563
+ */
+function parseFloat ($floatString){
+    $LocaleInfo = localeconv();
+    $floatString = str_replace($LocaleInfo['mon_thousands_sep'] , '', $floatString);
+    $floatString = str_replace($LocaleInfo['mon_decimal_point'] , '.', $floatString);
+    return floatval($floatString);
+}
+
+//-----------------------------------------------------------------------------
+//                        Configuration wrapper
+//-----------------------------------------------------------------------------
+
 // Getter for 'check_double_email'
 function getCheckDoubleEmail () {
        // Is the cache entry set?
@@ -2549,7 +2569,7 @@ function getCheckDoubleEmail () {
        return $GLOBALS[__FUNCTION__];
 }
 
-// Checks wether 'check_double_email' is "YES"
+// Checks wether 'check_double_email' is 'Y'
 function isCheckDoubleEmailEnabled () {
        // Is the cache entry set?
        if (!isset($GLOBALS[__FUNCTION__])) {
index 04550bc..8958bdb 100644 (file)
@@ -63,6 +63,13 @@ function showEntriesByXmlCallback ($template) {
                // Read it
                $templateContent = readFromFile($FQFN);
 
+               // Init main arrays
+               $GLOBALS['__XML_CALLBACKS'] = array(
+                       'callbacks' => array(),
+                       'functions' => array()
+               );
+               $GLOBALS['__XML_ARGUMENTS'] = array();
+
                // Handle it over to the parser
                parseXmlData($templateContent);
 
@@ -117,6 +124,15 @@ function doCallXmlCallbackFunction () {
                if ((isset($GLOBALS['__XML_CALLBACKS']['functions'][$callback])) && (isset($GLOBALS['__XML_ARGUMENTS'][$callback]))) {
                        // Run all function callbacks
                        foreach ($GLOBALS['__XML_CALLBACKS']['functions'][$callback] as $function) {
+                               // Trim all function names
+                               $function = trim($function);
+
+                               // If the function is empty, simply skip to the (maybe) next one
+                               if (empty($function)) {
+                                       // Skip this
+                                       continue;
+                               } // END - if
+
                                // Now construct the call-back function's name with 'Execute' at the end
                                $callbackName = $callback . 'Execute';
 
@@ -135,9 +151,9 @@ function doCallXmlCallbackFunction () {
        } // END - foreach
 }
 
-// ----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 //                     Call-back functions for XML parser
-// ----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 
 // Starts an element
 function startXmlElement ($resource, $element, $attributes) {
@@ -178,7 +194,7 @@ function isInvalidXmlType ($type) {
        $type = strtolower(trim($type));
 
        // Is it found?
-       return (in_array($type, array('string', 'array', 'bool')));
+       return (in_array($type, array('string', 'array', 'bool', 'int')));
 }
 
 // Checks if given value is valid/verifyable
index 9548a63..1a1215a 100644 (file)
@@ -1,5 +1,5 @@
 <tr>
-       <td align="center" class="{%template,ColorSwitch%} bottom right">[<strong>{%pipe,generateUserProfileLink=$content[url_userid]%}</strong>]</td>
+       <td align="center" class="{%template,ColorSwitch%} bottom right">{%pipe,generateUserProfileLink=$content[stats_userid]%}</td>
        <td align="center" class="{%template,ColorSwitch%} bottom right">{%pipe,translateComma=$content[total_visits]%}</td>
        <td align="center" class="{%template,ColorSwitch%} bottom">$content[last_surfed]</td>
 </tr>
index 6a53141..4ecd4e3 100644 (file)
@@ -30,7 +30,7 @@ MA  02110-1301  USA
        Call-back function which should all following parameter handled over
        to. This will always be type of string but we like homogene XMLs.
        //-->
-       <admin-callback-function type="string" value="adminDeleteEntriesConfirm" />
+       <callback-function type="string" value="adminDeleteEntriesConfirm" />
        <!--
        Array index from HTTP POST data array for identifying every data row
        //-->
index 6e32480..3d70110 100644 (file)
@@ -30,7 +30,7 @@ MA  02110-1301  USA
        Call-back function which should all following parameter handled over
        to. This will always be type of string but we like homogene XMLs.
        //-->
-       <admin-callback-function type="string" value="adminDeleteEntriesConfirm" />
+       <callback-function type="string" value="adminDeleteEntriesConfirm" />
        <!--
        Array index from HTTP POST data array for identifying every data row
        //-->
index 92ecc82..daa5e51 100644 (file)
@@ -30,7 +30,7 @@ MA  02110-1301  USA
        Call-back function which should all following parameter handled over
        to. This will always be type of string but we like homogene XMLs.
        //-->
-       <admin-callback-function type="string" value="adminEditEntriesConfirm" />
+       <callback-function type="string" value="adminEditEntriesConfirm" />
        <!--
        Array index from HTTP POST data array for identifying every data row
        //-->
index 7ab4786..7afa2ac 100644 (file)
@@ -30,7 +30,7 @@ MA  02110-1301  USA
        Call-back function which should all following parameter handled over
        to. This will always be type of string but we like homogene XMLs.
        //-->
-       <admin-callback-function type="string" value="adminEditEntriesConfirm" />
+       <callback-function type="string" value="adminEditEntriesConfirm" />
        <!--
        Array index from HTTP POST data array for identifying every data row
        //-->
diff --git a/templates/xml/admin/admin_list_surfbar_urls.xml b/templates/xml/admin/admin_list_surfbar_urls.xml
new file mode 100644 (file)
index 0000000..03391be
--- /dev/null
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+This template provides meta data for listing URLs of the surfbar in the admin
+area.
+
+@author                Roland Haeder <webmaster@mxchange.org>
+@version       0.2.1-FINAL
+@copyright     (c) 2003 - 2009 by Roland Haeder
+@copyright     (c) 2009 - 2011 by Mailer Developer Team
+@license       GNU GPL 2.0 or any newer version
+@link          http://www.mxchange.org
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+MA  02110-1301  USA
+//-->
+<admin-list-data>
+       <!--
+       Call-back function, the extracted data from this XML will then be re-read
+       from that function. The most common function this XML uses is
+       adminListEntries() so mostly you can leave this alone unless you have JOINs.
+       //-->
+       <callback-function type="string" value="adminListEntries" />
+       <!--
+       Now we need information which template should be loaded and which functions
+       shall be called back. So lets start with the main list template. This mostly
+       requires no call-back function.
+       //-->
+       <list-template type="string" value="admin_list_surfbar_urls" />
+       <!--
+       The template for all rows, mostly this name has a '_row' suffix and again,
+       no call-back function is usually required.
+       //-->
+       <list-row-template type="string" value="admin_list_surfbar_urls_row" />
+       <!--
+       The table(s) we shall grab the data from, all as list.
+       //-->
+       <data-tables>
+               <!--
+               A single table entry, with alias and without the configurable
+               _MYSQL_PREFIX. You can specify the table's name or alias later on.
+               //-->
+               <data-table type="string" alias="" value="surfbar_urls" />
+               <!--
+               Columns to perform the SELECT statement on, with alias and name plus which table.
+               //-->
+               <select-data-from-list>
+                       <!--
+                       A single entry with table name (can be left empty), value (must
+                       always be set), alias (again can be left empty) and SQL function
+                       (can also be left empty) which shall be applied on the column.
+                       //-->
+                       <select-data-from-list-entry type="string" table="" value="url_id" alias="" function="" />
+                       <select-data-from-list-entry type="string" table="" value="url_userid" alias="" function="" />
+                       <select-data-from-list-entry type="string" table="" value="url" alias="" function="" />
+                       <select-data-from-list-entry type="string" table="" value="url_views_total" alias="" function="" />
+                       <select-data-from-list-entry type="string" table="" value="url_status" alias="" function="" />
+                       <select-data-from-list-entry type="string" table="" value="url_registered" alias="url_registered" function="UNIX_TIMESTAMP" />
+                       <select-data-from-list-entry type="string" table="" value="url_last_locked" alias="url_last_locked" function="UNIX_TIMESTAMP" />
+                       <select-data-from-list-entry type="string" table="" value="url_lock_reason" alias="" function="" />
+               </select-data-from-list>
+               <!--
+               And the column list to perform the WHERE statement on.
+               //-->
+               <where-select-from-list>
+               </where-select-from-list>
+               <!--
+               Columns to perform the ORDER BY statement (GROUP BY is not yet supported)
+               //-->
+               <order-by-list>
+                       <!--
+                       A single entry to perform the ORDER BY statement on, see above WHERE entry for details.
+                       //-->
+                       <order-by-list-entry type="string" table="" order="url_id" value="ASC" />
+               </order-by-list>
+       </data-tables>
+       <!--
+       List all column names from the 'select-data-from-list' node here, but now
+       with call-back informations. The list must only contain those entries where
+       a call-back function shall be called for.
+       //-->
+       <column-callback-list>
+               <!--
+               Another column, now we need a second parameter here because
+               generateDateTime() expects two parameters (first is always the data
+               from column).
+               //-->
+               <column-callback-list-entry>
+                       <!--
+                       The actual data, again.
+                       //-->
+                       <column-callback-data type="string" value="url_registered" callback="generateDateTime" />
+                       <!--
+                       More parameters, remember that the first parameter is always given
+                       and that it is the data from column.
+                       //-->
+                       <callback-extra-parameter-list>
+                               <!--
+                               A single parameter, 'type' can be one of 'float', 'int',
+                               'bool', 'string'. 'array' is not yet supported.
+                               //-->
+                               <callback-extra-parameter-list-entry type="int" column="url_registered" value="2" />
+                       </callback-extra-parameter-list>
+               </column-callback-list-entry>
+               <!--
+               Second column to "translate".
+               //-->
+               <column-callback-list-entry>
+                       <column-callback-data type="string" value="url_last_locked" callback="generateDateTime" />
+                       <callback-extra-parameter-list>
+                               <callback-extra-parameter-list-entry type="int" column="url_last_locked" value="2" />
+                       </callback-extra-parameter-list>
+               </column-callback-list-entry>
+       </column-callback-list>
+       <!--
+       Message id to display if no entry could be found
+       //-->
+       <no-entry-found-message type="string" value="ADMIN_SURFBAR_NO_URLS_FOUND" />
+</admin-list-data>
index 49efcdd..1951a9b 100644 (file)
@@ -30,7 +30,7 @@ MA  02110-1301  USA
        Call-back function which should all following parameter handled over
        to. This will always be type of string but we like homogene XMLs.
        //-->
-       <admin-callback-function type="string" value="adminLockEntriesConfirm" />
+       <callback-function type="string" value="adminLockEntriesConfirm" />
        <!--
        Array index from HTTP POST data array for identifying every data row
        //-->
index 7494f78..870748f 100644 (file)
@@ -30,7 +30,7 @@ MA  02110-1301  USA
        Call-back function which should all following parameter handled over
        to. This will always be type of string but we like homogene XMLs.
        //-->
-       <admin-callback-function type="string" value="adminLockEntriesConfirm" />
+       <callback-function type="string" value="adminLockEntriesConfirm" />
        <!--
        Array index from HTTP POST data array for identifying every data row
        //-->
index 0fdb6b6..7910f59 100644 (file)
@@ -30,7 +30,7 @@ MA  02110-1301  USA
        Call-back function which should all following parameter handled over
        to. This will always be type of string but we like homogene XMLs.
        //-->
-       <admin-callback-function type="string" value="adminUndeleteEntriesConfirm" />
+       <callback-function type="string" value="adminUndeleteEntriesConfirm" />
        <!--
        Array index from HTTP POST data array for identifying every data row
        //-->
index 91ba504..2b80c60 100644 (file)
@@ -30,7 +30,7 @@ MA  02110-1301  USA
        Call-back function which should all following parameter handled over
        to. This will always be type of string but we like homogene XMLs.
        //-->
-       <admin-callback-function type="string" value="adminUndeleteEntriesConfirm" />
+       <callback-function type="string" value="adminUndeleteEntriesConfirm" />
        <!--
        Array index from HTTP POST data array for identifying every data row
        //-->
index c517d7a..6fc9904 100644 (file)
@@ -33,7 +33,7 @@ MA  02110-1301  USA
        to. This will always be type of string but we like homogene XMLs.
        Keep 'name' empty for numerical array indexes (array keys).
        //-->
-       <admin-callback-function type="string" value="adminFooEntriesBar" />
+       <callback-function type="string" value="adminFooEntriesBar" />
        <!--
        Array index from HTTP POST data array for identifying every data row
        //-->
diff --git a/templates/xml/admin_list_data_template.xml b/templates/xml/admin_list_data_template.xml
new file mode 100644 (file)
index 0000000..e47c537
--- /dev/null
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+This template is for other "list templates" and serves aas an example and most
+of it is not yet implemented (e.g. the table join part).
+
+@author                Roland Haeder <webmaster@mxchange.org>
+@version       0.2.1-FINAL
+@copyright     (c) 2003 - 2009 by Roland Haeder
+@copyright     (c) 2009 - 2011 by Mailer Developer Team
+@license       GNU GPL 2.0 or any newer version
+@link          http://www.mxchange.org
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+MA  02110-1301  USA
+//-->
+<admin-list-data>
+       <!--
+       Call-back function, the extracted data from this XML will then be re-read
+       from that function. The most common function this XML uses is
+       adminListEntries() so mostly you can leave this alone unless you have JOINs.
+       Use adminListJoinEntries for JOINs:
+       //-->
+       <callback-function type="string" value="adminListEntries" />
+       <!--
+       //-->
+       <!--
+       Now we need information which template should be loaded and which functions
+       shall be called back. So lets start with the main list template. This mostly
+       requires no call-back function.
+       //-->
+       <list-template type="string" value="admin_list_foo_data" />
+       <!--
+       The template for all rows, mostly this name has a '_row' suffix and again,
+       no call-back function is usually required.
+       //-->
+       <list-row-template type="string" value="admin_list_foo_data_row" />
+       <!--
+       The table(s) we shall grab the data from, all as list.
+       //-->
+       <data-tables>
+               <!--
+               A single table entry, with alias and without the configurable
+               _MYSQL_PREFIX. You can specify the table's name or alias later on.
+               //-->
+               <data-table type="string" alias="dt" value="data_table" />
+               <!--
+               A join condition to merge data from two or more tables, leave out
+               if you want to do simple SELECTs.
+               //-->
+               <table-join-condition>
+                       <!--
+                       The joining type, can be any valid SQL statement. Here it is an
+                       INNER JOIN (from both tables the data must exist).
+                       //-->
+                       <table-join-type type="INNER JOIN" />
+                       <!--
+                       Name (and alias) of the table we want to join
+                       //-->
+                       <table-join-name name="foo_data" alias="fd" />
+                       <!--
+                       On which condition these tables should join
+                       //-->
+                       <join-on>
+                               <!--
+                               The left table, name can also be an alias, column is the column
+                               of the left table.
+                               //-->
+                               <join-on-left-table type="string" name="dt" column="userid" />
+                               <!--
+                               Condition how these two tables should be joined.
+                               //-->
+                               <join-on-condition type="string" conditiion="EQUALS" />
+                               <!--
+                               And the corresponding right part.
+                               //-->
+                               <join-on-right-table type="string" name="fd" column="foo_userid" />
+                       </join-on>
+               </table-join-condition>
+               <!--
+               Columns to perform the SELECT statement on, with alias and name plus which table.
+               //-->
+               <select-data-from-list>
+                       <!--
+                       A single entry with table name (can be left empty), value (must
+                       always be set), alias (again can be left empty) and SQL function
+                       (can also be left empty) which shall be applied on the column.
+                       //-->
+                       <select-data-from-list-entry type="string" table="dt" value="gender" alias="" function="" />
+                       <select-data-from-list-entry type="string" table="dt" value="surname" alias="" function="" />
+                       <select-data-from-list-entry type="string" table="dt" value="family" alias="" function="" />
+                       <select-data-from-list-entry type="string" table="dt" value="last_online" alias="" function="" />
+               </select-data-from-list>
+               <!--
+               And the column list to perform the WHERE statement on.
+               //-->
+               <where-select-from-list>
+                       <!--
+                       A single entry to perform the WHERE statement on:
+                       - table     = table name (or alias)
+                       - name      = column name
+                       - condition = look-up condition
+                       - look-for  = What to look for
+                       //-->
+                       <where-select-from-list-entry type="string" table="dt" name="userid" condition="EQUALS" look-for="$userid" />
+                       <!--
+                       How the next described column shall be logical linked to the above.
+                       //-->
+                       <where-condition type="string" condition="AND" />
+                       <!--
+                       The second column to perform the WHERE statement on. NOT-EQUALS is an alias for '!='.
+                       //-->
+                       <where-select-from-list-entry type="string" table="dt" name="status" condition="NOT-EQUALS" look-for="CONFIRMED" />
+               </where-select-from-list>
+               <!--
+               Columns to perform the ORDER BY statement (GROUP BY is not yet supported)
+               //-->
+               <order-by-list>
+                       <!--
+                       A isingle entry to perform the ORDER BY statement on, see above WHERE entry for details.
+                       //-->
+                       <order-by-list-entry type="string" table="dt" order="userid" value="ASC" />
+                       <!--
+                       ORDER BY does also support more than one column, so we allow it here, too
+                       //-->
+                       <order-by-list-entry type="string" table="dt" order="foo_column" value="DESC" />
+               </order-by-list>
+       </data-tables>
+       <!--
+       List all column names from the 'select-data-from-list' node here, but now
+       with call-back informations. The list must only contain those entries where
+       a call-back function shall be called for.
+       //-->
+       <column-callback-list>
+               <!--
+               A single entry for call-back informations. In this example we want to
+               "translate" the gender information into human-readable.
+               //-->
+               <column-callback-list-entry>
+                       <!--
+                       The actual data.
+                       //-->
+                       <column-callback-data type="string" value="gender" callback="translateGender" />
+               </column-callback-list-entry>
+               <!--
+               Another column, now we need a second parameter here because
+               generateDateTime() expects two parameters (first is always the data
+               from column).
+               //-->
+               <column-callback-list-entry>
+                       <!--
+                       The actual data, again.
+                       //-->
+                       <column-callback-data type="string" value="last_online" callback="generateDateTime" />
+                       <!--
+                       More parameters, remember that the first parameter is always given
+                       and that it is the data from column.
+                       //-->
+                       <callback-extra-parameter-list>
+                               <!--
+                               A single parameter, 'type' can be one of 'float', 'int',
+                               'bool', 'string'. 'array' is not yet supported.
+                               //-->
+                               <callback-extra-parameter-list-entry type="int" column="last_online" value="2" />
+                       </callback-extra-parameter-list>
+               </column-callback-list-entry>
+       </column-callback-list>
+       <!--
+       Message id to display if no entry could be found
+       //-->
+       <no-entry-found-message type="string" value="ADMIN_SURFBAR_NO_URLS_FOUND" />
+</admin-list-data>