Changeset 2096

Show
Ignore:
Timestamp:
09/24/07 15:06:36 (16 months ago)
Author:
david
Message:

Added prototype ability to have validation field error messages inserted into the document by FormPopulationFilter?, refs #303

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • branches/0.11/src/filter/AgaviFormPopulationFilter.class.php

    r2091 r2096  
    343343        // there's an error with the element's name in the request? good. let's give the baby a class! 
    344344        if($vm->hasError($pname)) { 
     345          $errorMessages = $vm->getErrorMessages($pname); 
     346           
    345347          // a collection of all elements that need an error class 
    346348          $errorClassElements = array(); 
     
    364366              if($xpath->query(str_replace('%ns%', $ns, $xpathExpression), $errorClassElement)->length) { 
    365367                $errorClassElement->setAttribute('class', preg_replace('/\s*$/', ' ' . $errorClassName, $errorClassElement->getAttribute('class'))); 
    366                 // and break the foreach, our expression matched after all 
     368                // and break the foreach, our expression matched after all - no need to look further 
    367369                break; 
    368370              } 
    369371            } 
     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 
    370458          } 
    371459        } 
     
    576664    $this->setParameter('error_class', 'error'); 
    577665    $this->setParameter('error_class_map', array()); 
     666    $this->setParameter('error_messages', array()); 
    578667    $this->setParameter('force_output_mode', false); 
    579668    $this->setParameter('force_encoding', false); 
     
    605694    $this->setParameter('error_class_map', $errorClassMap); 
    606695     
     696    $this->setParameter('error_messages', (array) $this->getParameter('error_messages')); 
     697     
    607698    $this->setParameter('methods', (array) $this->getParameter('methods')); 
    608699