1: <?php
2: /**
3: * This code is licensed under AGPLv3 license or Afterlogic Software License
4: * if commercial version of the product was purchased.
5: * For full statements of the licenses see LICENSE-AFTERLOGIC and LICENSE-AGPL3 files.
6: */
7:
8: namespace Aurora\System\Xml;
9:
10: /**
11: * @license https://www.gnu.org/licenses/agpl-3.0.html AGPL-3.0
12: * @license https://afterlogic.com/products/common-licensing Afterlogic Software License
13: * @copyright Copyright (c) 2019, Afterlogic Corp.
14: *
15: * @package Api
16: */
17: class Node
18: {
19: /**
20: * @var string
21: */
22: public $TagName;
23:
24: /**
25: * @var string
26: */
27: public $Value;
28:
29: /**
30: * @var string
31: */
32: public $Comment;
33:
34: /**
35: * @var array
36: */
37: public $Attributes;
38:
39: /**
40: * @var array
41: */
42: public $Children;
43:
44: /**
45: * @param string $sTagName
46: * @param string $sValue = null
47: * @param bool $bIsCDATA = false
48: * @param bool $bIsSimpleCharsCode = false
49: * @param string $sNodeComment = ''
50: */
51: public function __construct($sTagName, $sValue = null, $bIsCDATA = false, $bIsSimpleCharsCode = false, $sNodeComment = '')
52: {
53: $this->Attributes = array();
54: $this->Children = array();
55:
56: $this->TagName = $sTagName;
57: $this->Value = ($bIsCDATA && null !== $sValue)
58: ? '<![CDATA['.
59: (($bIsSimpleCharsCode) ?
60: \Aurora\System\Utils::EncodeSimpleSpecialXmlChars($sValue) : \Aurora\System\Utils::EncodeSpecialXmlChars($sValue))
61: .']]>' : $sValue;
62:
63: $this->Comment = $sNodeComment;
64: }
65:
66: /**
67: * @param CXmlDomNode &$oNode
68: */
69: public function AppendChild(&$oNode)
70: {
71: if ($oNode) {
72: $this->Children[] =& $oNode;
73: }
74: }
75:
76: /**
77: * @param CXmlDomNode &$oNode
78: */
79: public function PrependChild(&$oNode)
80: {
81: if ($oNode) {
82: array_unshift($this->Children, $oNode);
83: }
84: }
85:
86: /**
87: * @param string $sName
88: * @param string $sValue
89: */
90: public function AppendAttribute($sName, $sValue)
91: {
92: $this->Attributes[$sName] = $sValue;
93: }
94:
95: /**
96: * @param string $sTagName
97: * @return &CXmlDomNode
98: */
99: public function &GetChildNodeByTagName($sTagName)
100: {
101: $iNodeKey = null;
102: $oCXmlDomNode = null;
103: $aNodeKeys = array_keys($this->Children);
104: foreach ($aNodeKeys as $iNodeKey) {
105: if ($this->Children[$iNodeKey] && $this->Children[$iNodeKey]->TagName === $sTagName) {
106: $oCXmlDomNode =& $this->Children[$iNodeKey];
107: break;
108: }
109: }
110: return $oCXmlDomNode;
111: }
112:
113: /**
114: * @param string $sTagName
115: * @return string
116: */
117: public function GetChildValueByTagName($sTagName)
118: {
119: $sResult = '';
120: $oNode =& $this->GetChildNodeByTagName($sTagName);
121: if (null !== $oNode) {
122: $sResult = \Aurora\System\Utils::DecodeSpecialXmlChars($oNode->Value);
123: }
124: return $sResult;
125: }
126:
127: /**
128: * @param bool $bSplitLines = false
129: * @return string
130: */
131: public function ToString($bSplitLines = false)
132: {
133: $sAttributes = '';
134: foreach ($this->Attributes as $sName => $sValue) {
135: $sName = htmlspecialchars($sName);
136: $sValue = htmlspecialchars($sValue);
137: $sAttributes .= ' '.$sName.'="'.$sValue.'"';
138: }
139:
140: $sChilds = '';
141: $iKeyIndex = null;
142: if (0 < count($this->Children)) {
143: foreach (array_keys($this->Children) as $iKeyIndex) {
144: $sChilds .= $this->Children[$iKeyIndex]->ToString($bSplitLines);
145: if ($bSplitLines) {
146: $sChilds .= "\r\n";
147: }
148: }
149:
150: if ($bSplitLines) {
151: $aLines = explode("\r\n", $sChilds);
152: $sChilds = '';
153: foreach ($aLines as $sLine) {
154: $sChilds .= ($sLine !== '') ? sprintf("\t%s\r\n", $sLine) : '';
155: }
156: }
157: }
158:
159: $sCommentPart = (empty($this->Comment)) ? '' : "<!-- ".$this->Comment." -->\r\n";
160:
161: if ($sChilds === '' && null === $this->Value) {
162: $sOutStr = sprintf('<%s%s />', $this->TagName, $sAttributes);
163: if ($bSplitLines) {
164: $sOutStr .= "\r\n";
165: }
166:
167: return $sCommentPart.$sOutStr;
168: }
169:
170: $sValue = (null !== $this->Value) ? trim($this->Value) : '';
171:
172: if ($bSplitLines) {
173: if ($sValue !== '' && $sChilds === '') {
174: return $sCommentPart.sprintf('<%s%s>%s</%s>', $this->TagName, $sAttributes, $sValue, $this->TagName);
175: }
176: if ($sValue === '' && $sChilds === '') {
177: return $sCommentPart.sprintf('<%s%s />', $this->TagName, $sAttributes);
178: }
179:
180: return $sCommentPart.sprintf("<%s%s>%s\r\n%s</%s>\r\n", $this->TagName, $sAttributes, $sValue, $sChilds, $this->TagName);
181: }
182:
183: return $sCommentPart.sprintf('<%s%s>%s%s</%s>', $this->TagName, $sAttributes, $sValue, $sChilds, $this->TagName);
184: }
185:
186: /**
187: * @param string $sName
188: * @param string $sDefault = null
189: * @return string
190: */
191: public function GetAttribute($sName, $sDefault = null)
192: {
193: return isset($this->Attributes[$sName]) ? \Aurora\System\Utils::DecodeSpecialXmlChars($this->Attributes[$sName]) : $sDefault;
194: }
195: }
196: