Back to Form class

Method load

public bool
load
(mixed $data, mixed $replace = true, mixed $xpath = null)
Method to load the form description from an XML string or object.
Parameters
  • string $data The name of an XML string or object.
  • bool $replace Flag to toggle whether form fields should be replaced if a field already exists with the same group/name.
  • string $xpath An optional xpath to search for the fields.
Returns
  • bool True on success, false otherwise.
Since
  • 1.7.0
Class: Form
Project: Joomla

Method load - Source code

/**
 * Method to load the form description from an XML string or object.
 *
 * The replace option works per field.  If a field being loaded already exists in the current
 * form definition then the behavior or load will vary depending upon the replace flag.  If it
 * is set to true, then the existing field will be replaced in its exact location by the new
 * field being loaded.  If it is false, then the new field being loaded will be ignored and the
 * method will move on to the next field to load.
 *
 * @param   string   $data     The name of an XML string or object.
 * @param   boolean  $replace  Flag to toggle whether form fields should be replaced if a field
 *                             already exists with the same group/name.
 * @param   string   $xpath    An optional xpath to search for the fields.
 *
 * @return  boolean  True on success, false otherwise.
 *
 * @since   1.7.0
 */
public function load($data, $replace = true, $xpath = null)
{
    // If the data to load isn't already an XML element or string return false.
    if (!$data instanceof \SimpleXMLElement && !\is_string($data)) {
        return false;
    }
    // Attempt to load the XML if a string.
    if (\is_string($data)) {
        try {
            $data = new \SimpleXMLElement($data);
        } catch (\Exception $e) {
            return false;
        }
    }
    // If we have no XML definition at this point let's make sure we get one.
    if (empty($this->xml)) {
        // If no XPath query is set to search for fields, and we have a <form />, set it and return.
        if (!$xpath && $data->getName() === 'form') {
            $this->xml = $data;
            // Synchronize any paths found in the load.
            $this->syncPaths();
            return true;
        } else {
            $this->xml = new \SimpleXMLElement('<form></form>');
        }
    }
    // Get the XML elements to load.
    $elements = [];
    if ($xpath) {
        $elements = $data->xpath($xpath);
    } elseif ($data->getName() === 'form') {
        $elements = $data->children();
    }
    // If there is nothing to load return true.
    if (empty($elements)) {
        return true;
    }
    // Load the found form elements.
    foreach ($elements as $element) {
        // Get an array of fields with the correct name.
        $fields = $element->xpath('descendant-or-self::field');
        foreach ($fields as $field) {
            // Get the group names as strings for ancestor fields elements.
            $attrs = $field->xpath('ancestor::fields[@name]/@name');
            $groups = array_map('strval', $attrs ?: []);
            // Check to see if the field exists in the current form.
            if ($current = $this->findField((string) $field['name'], implode('.', $groups))) {
                // If set to replace found fields, replace the data and remove the field so we don't add it twice.
                if ($replace) {
                    $olddom = dom_import_simplexml($current);
                    $loadeddom = dom_import_simplexml($field);
                    $addeddom = $olddom->ownerDocument->importNode($loadeddom, true);
                    $olddom->parentNode->replaceChild($addeddom, $olddom);
                    $loadeddom->parentNode->removeChild($loadeddom);
                } else {
                    unset($field);
                }
            }
        }
        // Merge the new field data into the existing XML document.
        self::addNode($this->xml, $element);
    }
    // Synchronize any paths found in the load.
    $this->syncPaths();
    return true;
}