Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 43 | class WSASoap {
|
||
| 44 | const WSANS = 'http://schemas.xmlsoap.org/ws/2004/08/addressing'; |
||
| 45 | const WSAPFX = 'wsa'; |
||
| 46 | private $soapNS, $soapPFX; |
||
| 47 | private $soapDoc = NULL; |
||
| 48 | private $envelope = NULL; |
||
| 49 | private $SOAPXPath = NULL; |
||
| 50 | private $header = NULL; |
||
| 51 | private $messageID = NULL; |
||
| 52 | |||
| 53 | private function locateHeader() {
|
||
| 54 | if ($this->header == NULL) {
|
||
| 55 | $headers = $this->SOAPXPath->query('//wssoap:Envelope/wssoap:Header');
|
||
| 56 | $header = $headers->item(0); |
||
| 57 | if (! $header) {
|
||
| 58 | $header = $this->soapDoc->createElementNS($this->soapNS, $this->soapPFX.':Header'); |
||
| 59 | $this->envelope->insertBefore($header, $this->envelope->firstChild); |
||
| 60 | } |
||
| 61 | $this->header = $header; |
||
| 62 | } |
||
| 63 | return $this->header; |
||
| 64 | } |
||
| 65 | |||
| 66 | public function __construct($doc) {
|
||
| 67 | $this->soapDoc = $doc; |
||
| 68 | $this->envelope = $doc->documentElement; |
||
| 69 | $this->soapNS = $this->envelope->namespaceURI; |
||
| 70 | $this->soapPFX = $this->envelope->prefix; |
||
| 71 | $this->SOAPXPath = new DOMXPath($doc); |
||
| 72 | $this->SOAPXPath->registerNamespace('wssoap', $this->soapNS);
|
||
| 73 | $this->SOAPXPath->registerNamespace('wswsa', self::WSANS);
|
||
| 74 | |||
| 75 | $this->envelope->setAttributeNS("http://www.w3.org/2000/xmlns/", 'xmlns:'.self::WSAPFX, self::WSANS);
|
||
| 76 | $this->locateHeader(); |
||
| 77 | } |
||
| 78 | |||
| 79 | public function addAction($action) {
|
||
| 80 | /* Add the WSA Action */ |
||
| 81 | $header = $this->locateHeader(); |
||
| 82 | |||
| 83 | $nodeAction = $this->soapDoc->createElementNS(self::WSANS, self::SAPFX.':Action', $action); |
||
| 84 | $header->appendChild($nodeAction); |
||
| 85 | } |
||
| 86 | |||
| 87 | public function addTo($location) {
|
||
| 88 | /* Add the WSA To */ |
||
| 89 | $header = $this->locateHeader(); |
||
| 90 | |||
| 91 | $nodeTo = $this->soapDoc->createElementNS(WSASoap::WSANS, WSASoap::WSAPFX.':To', $location); |
||
| 92 | $header->appendChild($nodeTo); |
||
| 93 | } |
||
| 94 | |||
| 95 | private function createID() {
|
||
| 96 | $uuid = md5(uniqid(rand(), true)); |
||
| 97 | $guid = 'uudi:'.substr($uuid,0,8)."-". |
||
| 98 | substr($uuid,8,4)."-". |
||
| 99 | substr($uuid,12,4)."-". |
||
| 100 | substr($uuid,16,4)."-". |
||
| 101 | substr($uuid,20,12); |
||
| 102 | return $guid; |
||
| 103 | } |
||
| 104 | |||
| 105 | public function addMessageID($id=NULL) {
|
||
| 106 | /* Add the WSA MessageID or return existing ID */ |
||
| 107 | if (! is_null($this->messageID)) {
|
||
| 108 | return $this->messageID; |
||
| 109 | } |
||
| 110 | |||
| 111 | if (empty($id)) {
|
||
| 112 | $id = $this->createID(); |
||
| 113 | } |
||
| 114 | |||
| 115 | $header = $this->locateHeader(); |
||
| 116 | |||
| 117 | $nodeID = $this->soapDoc->createElementNS(self::WSANS, self::WSAPFX.':MessageID', $id); |
||
| 118 | $header->appendChild($nodeID); |
||
| 119 | $this->messageID = $id; |
||
| 120 | } |
||
| 121 | |||
| 122 | public function addReplyTo($address = NULL) {
|
||
| 123 | /* Create Message ID is not already added - required for ReplyTo */ |
||
| 124 | if (is_null($this->messageID)) {
|
||
| 125 | $this->addMessageID(); |
||
| 126 | } |
||
| 127 | /* Add the WSA ReplyTo */ |
||
| 128 | $header = $this->locateHeader(); |
||
| 129 | |||
| 130 | $nodeReply = $this->soapDoc->createElementNS(self::WSANS, self::WSAPFX.':ReplyTo'); |
||
| 131 | $header->appendChild($nodeReply); |
||
| 132 | |||
| 133 | if (empty($address)) {
|
||
| 134 | $address = 'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous'; |
||
| 135 | } |
||
| 136 | $nodeAddress = $this->soapDoc->createElementNS(self::WSANS, self::WSAPFX.':Address', $address); |
||
| 137 | $nodeReply->appendChild($nodeAddress); |
||
| 138 | } |
||
| 139 | |||
| 140 | public function getDoc() {
|
||
| 141 | return $this->soapDoc; |
||
| 142 | } |
||
| 143 | |||
| 144 | public function saveXML() {
|
||
| 145 | return $this->soapDoc->saveXML(); |
||
| 146 | } |
||
| 147 | |||
| 148 | public function save($file) {
|
||
| 149 | return $this->soapDoc->save($file); |
||
| 150 | } |
||
| 151 | } |
||
| 152 | |||
| 153 |