/lib/recurly/resource.php

https://github.com/beaudesigns/recurly-client-php · PHP · 157 lines · 128 code · 23 blank · 6 comment · 29 complexity · 54f66ff8c2944acf628ce79355b135fd MD5 · raw file

  1. <?php
  2. abstract class Recurly_Resource extends Recurly_Base
  3. {
  4. protected $_values;
  5. protected $_unsavedKeys;
  6. protected $_errors;
  7. abstract protected function getNodeName();
  8. abstract protected function getWriteableAttributes();
  9. abstract protected function getRequiredAttributes();
  10. public function __construct($href = null, $client = null)
  11. {
  12. parent::__construct($href, $client);
  13. $this->_values = array();
  14. $this->_unsavedKeys = array();
  15. $this->_errors = new Recurly_ErrorList();
  16. }
  17. public function __set($k, $v)
  18. {
  19. $this->_values[$k] = $v;
  20. $this->_unsavedKeys[$k] = true;
  21. }
  22. public function __isset($k)
  23. {
  24. return isset($this->_values[$k]);
  25. }
  26. public function __unset($k)
  27. {
  28. unset($this->_values[$k]);
  29. }
  30. public function &__get($key)
  31. {
  32. if (isset($this->_values[$key])) {
  33. return $this->_values[$key];
  34. //} else if ($this->_attributes->include($key)) {
  35. // return null;
  36. } else if ($key == 'errors') {
  37. return $this->_errors;
  38. } else {
  39. $null_val = null;
  40. return $null_val;
  41. }
  42. }
  43. public function getErrors() {
  44. return $this->_errors;
  45. }
  46. protected function _save($method, $uri)
  47. {
  48. $this->_errors = array(); // reset errors
  49. if (is_null($this->_client))
  50. $this->_client = new Recurly_Client();
  51. $response = $this->_client->request($method, $uri, $this->xml());
  52. $response->assertValidResponse();
  53. if (isset($response->body)) {
  54. Recurly_Resource::__parseXmlToUpdateObject($response->body);
  55. }
  56. $response->assertSuccessResponse($this);
  57. }
  58. public function xml()
  59. {
  60. $doc = new DOMDocument("1.0");
  61. $root = $doc->appendChild($doc->createElement($this->getNodeName()));
  62. $this->populateXmlDoc($doc, $root, $this);
  63. return $doc->saveXML();
  64. }
  65. protected function populateXmlDoc(&$doc, &$node, &$obj, $nested = false)
  66. {
  67. $attributes = $obj->getChangedAttributes($nested);
  68. foreach ($attributes as $key => $val) {
  69. if ($val instanceof Recurly_CurrencyList) {
  70. $val->populateXmlDoc($doc, $node);
  71. } else if ($val instanceof Recurly_Resource) {
  72. $attribute_node = $node->appendChild($doc->createElement($key));
  73. $this->populateXmlDoc($doc, $attribute_node, $val, true);
  74. } else if (is_array($val)) {
  75. $attribute_node = $node->appendChild($doc->createElement($key));
  76. foreach ($val as $child => $childValue) {
  77. if (is_null($child) || is_null($childValue)) {
  78. continue;
  79. }
  80. elseif (is_string($child)) {
  81. // e.g. "<discount_in_cents><USD>1000</USD></discount_in_cents>"
  82. $attribute_node->appendChild($doc->createElement($child, $childValue));
  83. }
  84. elseif (is_int($child)) {
  85. if (is_object($childValue)) {
  86. // e.g. "<subscription_add_ons><subscription_add_on>...</subscription_add_on></subscription_add_ons>"
  87. $childValue->populateXmlDoc($doc, $attribute_node, $childValue);
  88. }
  89. elseif (substr($key, -1) == "s") {
  90. // e.g. "<plan_codes><plan_code>gold</plan_code><plan_code>monthly</plan_code></plan_codes>"
  91. $attribute_node->appendChild($doc->createElement(substr($key, 0, -1), $childValue));
  92. }
  93. }
  94. }
  95. } else {
  96. if ($val instanceof DateTime) {
  97. $val = $val->format('c');
  98. } else if (is_bool($val)) {
  99. $val = ($val ? 1 : 0);
  100. }
  101. $node->appendChild($doc->createElement($key, $val));
  102. }
  103. }
  104. }
  105. protected function getChangedAttributes($nested = false)
  106. {
  107. $attributes = array();
  108. $writableAttributes = $this->getWriteableAttributes();
  109. $requiredAttributes = $this->getRequiredAttributes();
  110. foreach($writableAttributes as $attr) {
  111. if(!isset($this->_values[$attr])) { continue; }
  112. if(isset($this->_unsavedKeys[$attr]) ||
  113. $nested && in_array($attr, $requiredAttributes) ||
  114. (is_array($this->_values[$attr]) || $this->_values[$attr] instanceof ArrayAccess))
  115. {
  116. $attributes[$attr] = $this->$attr;
  117. }
  118. }
  119. return $attributes;
  120. }
  121. protected function updateErrorAttributes()
  122. {
  123. if (sizeof($this->_errors) > 0) {
  124. for ($i = sizeof($this->_errors) - 1; $i >= 0; $i--) {
  125. $error = $this->_errors[$i];
  126. if (isset($error->field)) {
  127. if (substr($error->field, 0, strlen($this->getNodeName()) + 1) == ($this->getNodeName() . '.'))
  128. $error->field = substr($error->field, strlen($this->getNodeName()) + 1);
  129. }
  130. // TODO: If there are more dots, then apply these to sub elements
  131. }
  132. }
  133. }
  134. }