/microsoft/src/main/php/com/microsoft/com/COMObject.class.php

https://github.com/Gamepay/xp-contrib · PHP · 206 lines · 98 code · 15 blank · 93 comment · 14 complexity · 685ca44db58e801476aba5813a324714 MD5 · raw file

  1. <?php
  2. /* This class is part of the XP framework
  3. *
  4. * $Id$
  5. */
  6. uses('com.microsoft.com.COMObjectIterator');
  7. /**
  8. * COM object
  9. *
  10. * <quote>
  11. * COM is a technology which allows the reuse of code written in any language
  12. * (by any language) using a standard calling convention and hiding behind
  13. * APIs the implementation details such as what machine the Component is
  14. * stored on and the executable which houses it. It can be thought of as a
  15. * super Remote Procedure Call (RPC) mechanism with some basic object roots.
  16. * It separates implementation from interface.
  17. *
  18. * COM encourages versioning, separation of implementation from interface and
  19. * hiding the implementation details such as executable location and the
  20. * language it was written in.
  21. * </quote>
  22. *
  23. * @see http://www.microsoft.com/Com/resources/comdocs.asp COM specification
  24. * @see http://www.developmentor.com/dbox/yacl.htm Yet Another COM Library (YACL)
  25. * @ext com
  26. * @test xp://com.microsoft.unittest.COMObjectTest
  27. * @platform Windows
  28. */
  29. class COMObject extends Object implements IteratorAggregate, ArrayAccess {
  30. protected $h= NULL;
  31. /**
  32. * Constructor
  33. *
  34. * @param string identifier
  35. * @param string server default NULL
  36. */
  37. public function __construct($identifier, $server= NULL) {
  38. if ($identifier instanceof COM || $identifier instanceof Variant) {
  39. $this->h= $identifier;
  40. } else {
  41. try {
  42. $this->h= new COM($identifier, $server);
  43. } catch (com_exception $e) {
  44. throw new IllegalArgumentException($e->getCode().': '.$e->getMessage());
  45. }
  46. }
  47. }
  48. /**
  49. * Magic interceptor for member read access
  50. *
  51. * @param string name
  52. * @return var value
  53. */
  54. public function __get($name) {
  55. try {
  56. $v= $this->h->{$name};
  57. if ($v instanceof COM || $v instanceof Variant) {
  58. return new self($v);
  59. } else {
  60. return $v;
  61. }
  62. } catch (com_exception $e) {
  63. throw new IllegalArgumentException($e->getCode().': '.$e->getMessage());
  64. }
  65. }
  66. /**
  67. * Magic interceptor for member write access
  68. *
  69. * @param string name
  70. * @param var value
  71. */
  72. public function __set($name, $value) {
  73. try {
  74. if ($value instanceof self) {
  75. $this->h->{$name}= $value->h;
  76. } else {
  77. $this->h->{$name}= $value;
  78. }
  79. } catch (com_exception $e) {
  80. throw new IllegalArgumentException($e->getCode().': '.$e->getMessage());
  81. }
  82. }
  83. /**
  84. * Magic interceptor for member method access
  85. *
  86. * @param string name
  87. * @param var[] args
  88. * @return var return
  89. */
  90. public function __call($name, $args) {
  91. $pass= array();
  92. foreach ($args as $i => $value) {
  93. if ($value instanceof self) {
  94. $pass[]= $value->h;
  95. } else {
  96. $pass[]= $value;
  97. }
  98. }
  99. // call_user_func_array() will raise an error here if:
  100. // a) The method doesn't exists
  101. // b) The argument doesn't match the signature
  102. try {
  103. $l= __LINE__; $v= call_user_func_array(array($this->h, $name), $pass);
  104. if (isset(xp::$registry['errors'][__FILE__][$l])) {
  105. $error= key(xp::$registry['errors'][__FILE__][$l]);
  106. xp::gc(__FILE__);
  107. throw new IllegalArgumentException($error);
  108. }
  109. } catch (com_exception $e) {
  110. throw new IllegalArgumentException($e->getCode().': '.$e->getMessage());
  111. }
  112. if ($v instanceof COM || $v instanceof Variant) {
  113. return new self($v);
  114. } else {
  115. return $v;
  116. }
  117. }
  118. /**
  119. * Returns an iterator for use in foreach()
  120. *
  121. * @return var
  122. */
  123. public function getIterator() {
  124. $iteration= array();
  125. foreach ($this->h as $i => $value) {
  126. $iteration[$i]= $value;
  127. }
  128. return new COMObjectIterator($iteration);
  129. }
  130. /**
  131. * = list[] overloading
  132. *
  133. * @param var offset
  134. * @return var
  135. * @throws lang.IndexOutOfBoundsException if key does not exist
  136. */
  137. public function offsetGet($offset) {
  138. try {
  139. return $this->h[$offset];
  140. } catch (com_exception $e) {
  141. throw new IllegalArgumentException($e->getCode().': '.$e->getMessage());
  142. }
  143. }
  144. /**
  145. * list[]= overloading
  146. *
  147. * @param var offset
  148. * @param var value
  149. * @throws lang.IllegalArgumentException if key is neither numeric (set) nor NULL (add)
  150. */
  151. public function offsetSet($offset, $value) {
  152. $this->h[$offset]= $value;
  153. }
  154. /**
  155. * isset() overloading
  156. *
  157. * @param var offset
  158. * @return bool
  159. */
  160. public function offsetExists($offset) {
  161. return isset($this->h[$offset]);
  162. }
  163. /**
  164. * unset() overloading
  165. *
  166. * @param var offset
  167. */
  168. public function offsetUnset($offset) {
  169. unset($this->h[$offset]);
  170. }
  171. /**
  172. * Destructor
  173. *
  174. */
  175. public function __destruct() {
  176. $this->h= NULL;
  177. }
  178. /**
  179. * Creates a string representation of this object
  180. *
  181. * @return string
  182. */
  183. public function toString() {
  184. ob_start();
  185. com_print_typeinfo($this->h);
  186. preg_match('/class ([^ ]+) \{ \/\* GUID=([^ ]+) \*\//', ob_get_contents(), $matches);
  187. ob_end_clean();
  188. return $this->getClassName().'(->'.get_class($this->h).'<'.$matches[1].'>@'.$matches[2].')';
  189. }
  190. }
  191. ?>