You are here

function configuration_check_context in Configuration Management 6

Check and fix the integrity of the context object in case changes were made to the data

TODO If performance seems to be a problem, test using checksums against the data to determine if changes have been made


$context: The referenced context object needing checked and possibly fixed.

1 call to configuration_check_context()
configuration_context_process_property in ./configuration.module
Process a single mapping config property. Various properties will mark static data that will be processed later on in the configuration phases.


./configuration.module, line 1604
Provide a unified method for defining site configurations abstracted from their data format. Various data formats should be supported via a plugin architecture such as XML, YAML, JSON, PHP


function configuration_check_context(&$context) {

  // Start from the top of the context
  while (isset($context->parent)) {
    $context =& $context->parent;

  // Start the check array that will recurse through the context.
  // Set it to the first item that has a key/parent instead of the root.
  $checklist = array(
  while ($check =& $checklist[0]) {

    // Check if this particular item has been removed.
    if (!isset($check->parent->item[$check->key])) {

      // Find this context item in the parent and remove it
      for ($i = 0; isset($check->parent->children[$i]); $i++) {
        $find =& $check->parent->children[$i];
        if ($find === $check) {

          // We need to set it to null as well as unsetting it so that
          // any existing references pointing to it will be unset. We can't
          // splice here either because of the reorder later on
          $check = null;
      $check_order = true;

    // Check if an item that didn't exist before is here
    if (is_array($check->parent->item) && !empty($check->parent->item)) {
      $keys = array_keys($check->parent->item);
      $keys = array_combine($keys, $keys);
      for ($i = 0; isset($check->parent->children[$i]); $i++) {

      // Any left overs here should be new. $i should be set to where the next item should be set
      if (!empty($keys)) {
        foreach ($keys as $key) {
          $check->parent->children[$i++] = configuration_build_context($check->parent->item[$key], $key, configuration_trace_context($check->parent), $check->parent);

    // Check that this contexts data changed from no children to having children
    // The above check will pick up additional children when there some to start
    if (empty($check->children) && is_array($check->item) && !empty($check->item)) {
      $i = 0;
      foreach ($check->item as $key => &$data) {
        $check->children[$i] = configuration_build_context($check->item[$key], $key, configuration_trace_context($check), $check);

    // Check that this context data changed from having children to no children
    if (!empty($check->children) && !is_array($check->item)) {
      for ($i = 0; isset($check->children[$i]); $i++) {
        $check->children[$i] = null;

    // If this is marked empty, but is not, remove marker
    if ($check->empty && isset($check->item)) {

    // Check if a reorder for an indexed array is needed and reorder
    // TODO Make an appropriate test case and test this
    if ($check_order) {
      if (isset($check->parent->item[0]) || isset($check->parent->item[1])) {

        // First go to the hole in the indexed array
        for ($i = 0; isset($check->parent->item[$i]); $i++) {

        // Confirm that the context does not exist or remove it
        if (isset($check->parent->children[$i])) {
          $check->parent->children[$i] = null;

        // Move all the consecutive items back one
        while (isset($check->parent->item[++$i])) {
          $fix =& $check->parent->children[$i];
          $check->parent->item[$i - 1] =& $fix->item;

          // Fix the key
          $fix->key = $i - 1;

          // Fix child traces

        // Remove the last item since it was moved up one
        unset($check->parent->item[$i - 1]);

        // Sort on the index to finish up

        // Sort the children contexts as well
        usort($check->children, '_configuration_sort_context');
    $i = 0;
    while (isset($check->children[$i])) {
      $checklist[count($checklist)] =& $check->children[$i++];