| | 372 | } |
| | 373 | |
| | 374 | $luie = libxml_use_internal_errors(true); |
| | 375 | libxml_clear_errors(); |
| | 376 | |
| | 377 | $didInsertMessages = false; |
| | 378 | // and next: see if we're supposed to insert an error message somewhere |
| | 379 | foreach($cfg['error_messages'] as $xpathExpression => $errorMessageInfo) { |
| | 380 | $targets = $xpath->query(str_replace('%ns%', $ns, $xpathExpression), $element); |
| | 381 | if($targets->length) { |
| | 382 | if(is_array($errorMessageInfo)) { |
| | 383 | $elementInfo = $errorMessageInfo['element']; |
| | 384 | $locationInfo = $errorMessageInfo['location']; |
| | 385 | } else { |
| | 386 | $elementInfo = $errorMessageInfo; |
| | 387 | $locationInfo = 'after'; |
| | 388 | } |
| | 389 | |
| | 390 | // TODO: special syntax for handling of multiple error messages |
| | 391 | // e.g. one might want to have a container for all of them, and then individual fragments of markup for each message |
| | 392 | foreach($errorMessages as $errorMessage) { |
| | 393 | if(is_string($elementInfo)) { |
| | 394 | // it's a string with the HTML to insert |
| | 395 | // %s is the placeholder in the HTML for the error message |
| | 396 | $errorMessageElement = $doc->createDocumentFragment(); |
| | 397 | $errorMessageElement->appendXML(sprintf($elementInfo, $errorMessage)); |
| | 398 | } elseif(is_callable($elementInfo)) { |
| | 399 | // it's a callback we can use to get a DOMElement |
| | 400 | // we give it the element as the first, and the error message as the second argument |
| | 401 | $errorMessageElement = call_user_func(elementInfo, $element, $errorMessage); |
| | 402 | $doc->importNode($errorMessageNode, true); |
| | 403 | } else { |
| | 404 | throw new AgaviException('Form Population Filter was unable to insert an error message into the document using the XPath expression "' . $xpathExpression . '" because the element information could not be evaluated as an XML/HTML fragment or as a PHP callback.'); |
| | 405 | } |
| | 406 | |
| | 407 | if(libxml_get_last_error() !== false) { |
| | 408 | $errors = array(); |
| | 409 | foreach(libxml_get_errors() as $error) { |
| | 410 | $errors[] = sprintf("Line %d: %s", $error->line, $error->message); |
| | 411 | } |
| | 412 | libxml_clear_errors(); |
| | 413 | libxml_use_internal_errors($luie); |
| | 414 | $emsg = sprintf( |
| | 415 | 'Form Population Filter was unable to insert an error message into the document using the XPath expression "%s" due to the following error%s: ' . "\n\n%s", |
| | 416 | $xpathExpression, |
| | 417 | count($errors) > 1 ? 's' : '', |
| | 418 | implode("\n", $errors) |
| | 419 | ); |
| | 420 | if(AgaviConfig::get('core.use_logging') && $cfg['log_parse_errors']) { |
| | 421 | $lmsg = $emsg . "\n\nResponse content:\n\n" . $response->getContent(); |
| | 422 | $lm = $this->context->getLoggerManager(); |
| | 423 | $mc = $lm->getDefaultMessageClass(); |
| | 424 | $m = new $mc($lmsg, $cfg['logging_severity']); |
| | 425 | $lm->log($m, $cfg['logging_logger']); |
| | 426 | } |
| | 427 | throw new AgaviParseException($emsg); |
| | 428 | } |
| | 429 | |
| | 430 | foreach($targets as $target) { |
| | 431 | if($locationInfo == 'before') { |
| | 432 | $target->parentNode->insertBefore($errorMessageElement, $target); |
| | 433 | } elseif($locationInfo == 'after') { |
| | 434 | // check if there is a following sibling, then insert before that one |
| | 435 | // if not, append to parent |
| | 436 | if($target->nextSibling) { |
| | 437 | $target->parentNode->insertBefore($errorMessageElement, $target->nextSibling); |
| | 438 | } else { |
| | 439 | $target->parentNode->appendChild($errorMessageElement); |
| | 440 | } |
| | 441 | } else { |
| | 442 | $target->appendChild($errorMessageElement); |
| | 443 | } |
| | 444 | } |
| | 445 | } |
| | 446 | |
| | 447 | // and break the foreach, our expression matched after all - no need to look further |
| | 448 | $didInsertMessages = true; |
| | 449 | break; |
| | 450 | } |
| | 451 | } |
| | 452 | |
| | 453 | libxml_clear_errors(); |
| | 454 | libxml_use_internal_errors($luie); |
| | 455 | |
| | 456 | if(!$didInsertMessages) { |
| | 457 | // TODO: collect the error messages that could not be inserted in a request attribute |