FileStorage.php 3.57 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
<?php

namespace Drupal\Core\Config;

/**
 * Represents the file storage interface.
 *
 * Classes implementing this interface allow reading and writing configuration
 * data to and from disk.
 */
class FileStorage {

  /**
   * Constructs a FileStorage object.
   *
   * @param string $name
   *   The name for the configuration data. Should be lowercase.
   */
  public function __construct($name) {
    $this->name = $name;
  }

  /**
   * Reads and returns a file.
   *
   * @return
   *   The data of the file.
   *
   * @throws
   *   Exception
   */
  protected function readData() {
    $data = file_get_contents($this->getFilePath());
    if ($data === FALSE) {
35
      throw new FileStorageReadException('Read file is invalid.');
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
    }
    return $data;
  }

  /**
   * Checks whether the XML configuration file already exists on disk.
   *
   * @return
   *   @todo
   */
  protected function exists() {
    return file_exists($this->getFilePath());
  }

  /**
   * Returns the path to the XML configuration file.
   *
   * @return
   *   @todo
   */
  public function getFilePath() {
    return config_get_config_directory() . '/' . $this->name  . '.xml';
  }

  /**
   * Writes the contents of the configuration file to disk.
   *
   * @param $data
   *   The data to be written to the file.
   *
   * @throws
   *   Exception
   */
  public function write($data) {
70
    $data = $this->encode($data);
71
    if (!file_put_contents($this->getFilePath(), $data)) {
72
      throw new FileStorageException('Failed to write configuration file: ' . $this->getFilePath());
73 74 75 76 77 78 79 80 81 82 83 84
    }
  }

  /**
   * Returns the contents of the configuration file.
   *
   * @return
   *   @todo
   */
  public function read() {
    if ($this->exists()) {
      $data = $this->readData();
85
      return $this->decode($data);
86 87 88 89 90 91 92 93 94 95 96
    }
    return FALSE;
  }

  /**
   * Deletes a configuration file.
   */
  public function delete() {
    // Needs error handling and etc.
    @drupal_unlink($this->getFilePath());
  }
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156

  /**
   * Implements StorageInterface::encode().
   */
  public static function encode($data) {
    // Convert the supplied array into a SimpleXMLElement.
    $xml_object = new \SimpleXMLElement("<?xml version=\"1.0\"?><config></config>");
    self::encodeArrayToXml($data, $xml_object);

    // Pretty print the result.
    $dom = new \DOMDocument('1.0');
    $dom->preserveWhiteSpace = false;
    $dom->formatOutput = true;
    $dom->loadXML($xml_object->asXML());

    return $dom->saveXML();
  }

  /**
   * Encodes an array into XML
   *
   * @param $array
   *   An associative array to encode.
   *
   * @return
   *   A representation of $array in XML.
   */
  protected static function encodeArrayToXml($array, &$xml_object) {
    foreach ($array as $key => $value) {
      if (is_array($value)) {
        if (!is_numeric($key)){
          $subnode = $xml_object->addChild("$key");
          self::encodeArrayToXml($value, $subnode);
        }
        else {
          self::encodeArrayToXml($value, $xml_object);
        }
      }
      else {
        $xml_object->addChild($key, $value);
      }
    }
  }

  /**
   * Implements StorageInterface::decode().
   */
  public static function decode($raw) {
    if (empty($raw)) {
      return array();
    }

    // This is the fastest and easiest way to get from a string of XML to a PHP
    // array since SimpleXML and json_decode()/encode() are native to PHP. Our
    // only other choice would be a custom userspace implementation which would
    // be a lot less performant and more complex.
    $xml = new \SimpleXMLElement($raw);
    $json = json_encode($xml);
    return json_decode($json, TRUE);
  }
157
}