Rewrote 'we' word a little, rewrote mail order to use SQL_INSERTID() instead of anoth...
[mailer.git] / inc / xml-functions.php
index 94a9b6a0ed43f82e04506fdd51056054575456d8..c3cfa51b0be8109eeb207bdbfd813cd1462c698b 100644 (file)
@@ -16,8 +16,8 @@
  * $Author::                                                          $ *
  * -------------------------------------------------------------------- *
  * Copyright (c) 2003 - 2009 by Roland Haeder                           *
- * Copyright (c) 2009 - 2011 by Mailer Developer Team                   *
- * For more information visit: http://www.mxchange.org                  *
+ * Copyright (c) 2009 - 2012 by Mailer Developer Team                   *
+ * For more information visit: http://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 *
@@ -40,5 +40,285 @@ if (!defined('__SECURITY')) {
        die();
 } // END - if
 
+// Calls back a function based on given XML template data
+function showEntriesByXmlCallback ($template) {
+       // Generate FQFN for with special path
+       $FQFN = sprintf("%stemplates/xml/%s%s.xml",
+               getPath(),
+               detectExtraTemplatePath($template),
+               $template
+       );
+
+       // Is the file readable?
+       if (!isFileReadable($FQFN)) {
+               // No, use without extra path
+               $FQFN = sprintf("%stemplates/xml/%s.xml",
+                       getPath(),
+                       $template
+               );
+       } // END - if
+
+       // Is it again readable?
+       if (isFileReadable($FQFN)) {
+               // Read it
+               $templateContent = readFromFile($FQFN);
+
+               // Init main arrays
+               $GLOBALS['__XML_CALLBACKS'] = array(
+                       'callbacks' => array(),
+                       'functions' => array()
+               );
+               $GLOBALS['__XML_ARGUMENTS'] = array();
+               $GLOBALS['__COLUMN_INDEX']  = array();
+
+               // Handle it over to the parser
+               parseXmlData($templateContent);
+
+               // Add special elements, e.g. column index
+               addXmlSpecialElements($template);
+
+               // Call the call-back function
+               doCallXmlCallbackFunction();
+       } else {
+               // Template not found
+               displayMessage('{%message,XML_TEMPLATE_404=' . $template . '%}');
+       }
+}
+
+// Adds special elements by calling back another template-depending function
+function addXmlSpecialElements ($template) {
+       // Generate the FQCN (Full-Qualified CallbackName)
+       $FQCN = 'addXmlSpecial' . capitalizeUnderscoreString($template);
+
+       // Is it there?
+       if (function_exists($FQCN)) {
+               // Call it
+               call_user_func($FQCN);
+       } elseif (isDebugModeEnabled()) {
+               // This callback function is only optional
+               logDebugMessage(__FUNCTION__, __LINE__, 'Call-back function ' . $FQCN . ' for template ' . $template . ' does not exist.');
+       }
+}
+
+// Parses the XML content
+function parseXmlData ($content) {
+       // Is there recode?
+       if (!function_exists('recode')) {
+               // No fallback ATM
+               reportBug('PHP extension recode is missing. Please install it.');
+       } // END - if
+
+       // Convert HTML entities to UTF-8
+       $content = recode('html..utf8', $content);
+
+       // Create a new XML parser
+       $xmlParser = xml_parser_create();
+
+       // Force case-folding to on
+       xml_parser_set_option($xmlParser, XML_OPTION_CASE_FOLDING, true);
+
+       // Set UTF-8
+       xml_parser_set_option($xmlParser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
+
+       // Set handler call-backs
+       xml_set_element_handler($xmlParser, 'startXmlElement', 'endXmlElement');
+       xml_set_character_data_handler($xmlParser, 'xmlCharacterHandler');
+
+       // Now parse the XML tree
+       if (!xml_parse($xmlParser, $content)) {
+               // Error found in XML!
+               //* DEBUG: */ die('<pre>'.htmlentities($content).'</pre>');
+               reportBug(__FUNCTION__, __LINE__, 'Error found in XML. errorMessage=' . xml_error_string(xml_get_error_code($xmlParser)) . ', line=' . xml_get_current_line_number($xmlParser));
+       } // END - if
+
+       // Free the parser
+       xml_parser_free($xmlParser);
+}
+
+// Calls the found call-back function
+function doCallXmlCallbackFunction () {
+       // Loop through all added entries
+       foreach ($GLOBALS['__XML_CALLBACKS']['callbacks'] as $callback) {
+               // Is there the entry?
+               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';
+
+                               // Is it there?
+                               if (!function_exists($callbackName)) {
+                                       // No, then please add it
+                                       reportBug(__FUNCTION__, __LINE__, 'callback=' . $callback . ',function=' . $function . 'arguments()=' . count($GLOBALS['__XML_ARGUMENTS'][$callback]) . ' - execute call-back does not exist.');
+                               } // END - if
+
+                               // Call it
+                               call_user_func_array($callbackName, array($function, $GLOBALS['__XML_ARGUMENTS'][$callback], $GLOBALS['__COLUMN_INDEX'][$callback]));
+                       } // END - foreach
+               } else {
+                       // Not found
+                       reportBug(__FUNCTION__, __LINE__, 'Entry in callbacks does exist, but not in functions, callback= ' . $callback);
+               }
+       } // END - foreach
+}
+
+//-----------------------------------------------------------------------------
+//                     Call-back functions for XML parser
+//-----------------------------------------------------------------------------
+
+// Starts an element
+function startXmlElement ($resource, $element, $attributes) {
+       // Call-back function for given element
+       $elementCallback = 'doXml' . capitalizeUnderscoreString($element);
+
+       // Is the call-back function there?
+       if (!function_exists($elementCallback)) {
+               // Not there
+               reportBug(__FUNCTION__, __LINE__, 'Missing call-back function ' . $elementCallback . ', please add it.');
+       } // END - if
+
+       // Call the call-back function
+       call_user_func_array($elementCallback, array($resource, $attributes));
+}
+
+// Ends an element
+function endXmlElement ($resource, $element) {
+       // Out-of-function for now
+}
+
+// Handle characters
+function xmlCharacterHandler ($resource, $characters) {
+       // Trim spaces away
+       $characters = trim($characters);
+
+       // Are there some to handle?
+       if (strlen($characters) == 0) {
+               // Nothing to handle
+               return;
+       } // END - if
+
+       // @TODO Handle characters
+       die(__FUNCTION__ . ':characters[]='.strlen($characters));
+}
+
+// Checks if given type is valid, makes all lower-case
+function isInvalidXmlType ($type) {
+       // All lower-case
+       $type = strtolower(trim($type));
+
+       // Is it found?
+       return (in_array($type, array('string', 'array', 'bool', 'int', 'callback')));
+}
+
+// Checks if given condition is valid
+function isXmlConditionValid ($condition) {
+       // Trim and make lower-case
+       $condition = trim(strtolower($condition));
+
+       // Is it valid?
+       return (in_array($condition, array('equals')));
+}
+
+// Checks if given value is valid/verifyable
+function isXmlValueValid ($type, $value) {
+       // Depends on type, so build a call-back
+       $callbackName = 'isXmlType' . trim(capitalizeUnderscoreString($type));
+
+       // Is the call-back function there?
+       if (!function_exists($callbackName)) {
+               // Not there
+               reportBug(__FUNCTION__, __LINE__, 'Missing call-back function ' . $callbackName . ', please add it.');
+       } // END - if
+
+       // Call and return it
+       return call_user_func_array($callbackName, array($value));
+}
+
+// Converts given condition into a symbol
+function convertXmlContion ($condition) {
+       // Default is an invalid one
+       $return = '???';
+
+       // Detect the condition again
+       switch ($condition) {
+               case 'EQUALS': // Equals
+                       $return = '=';
+                       break;
+
+               default: // Unknown condition
+                       reportBug(__FUNCTION__, __LINE__, 'Condition ' . $condition . ' is unknown/unsupported.');
+                       break;
+       } // END - switch
+
+       // Return it
+       return $return;
+}
+
+// "Getter" for sql part back from given array
+function getSqlPartFromXmlArray ($columns) {
+       // Init SQL
+       $SQL = '';
+
+       // Walk through all entries
+       foreach ($columns as $columnArray) {
+               // Init SQL part
+               $sqlPart = '';
+
+               // Is there 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
+
+       // Return it without last commata
+       return substr($SQL, 0, -1);
+}
+
+// Searches in given XML array for value and returns the parent index
+function searchXmlArray ($value, $columns, $childKey) {
+       // Default is not found
+       $return = false;
+
+       // Walk through whole array
+       foreach ($columns as $key => $columnArray) {
+               // Make sure the element is there
+               assert(isset($columnArray[$childKey]));
+
+               // Now is it what we are looking for?
+               if ($columnArray[$childKey] == $value) {
+                       // Remember this match
+                       $return = $key;
+
+                       // And abort any further searches
+                       break;
+               } // END - if
+       } // END - foreach
+
+       // Return key/false
+       return $return;
+}
+
 // [EOF]
 ?>