1: <?php
2:
3:
4: namespace BeerXML\Parser;
5:
6:
7: use BeerXML\Exception\BadData;
8:
9: 10: 11: 12: 13: 14: 15: 16:
17: abstract class Record
18: {
19: 20: 21: 22: 23:
24: protected $tagName = null;
25:
26: 27: 28:
29: protected $xmlReader;
30:
31: 32: 33:
34: protected $recordFactory;
35:
36: 37: 38: 39: 40:
41: protected $simpleProperties = array();
42:
43: protected $complexProperties = array(
44: 'STYLE' => array(
45: 'parser' => '\BeerXML\Parser\Style',
46: 'method' => 'setStyle'
47: ),
48: 'EQUIPMENT' => array(
49: 'parser' => '\BeerXML\Parser\Equipment',
50: 'method' => 'setEquipment'
51: ),
52: 'MASH' => array(
53: 'parser' => '\BeerXML\Parser\MashProfile',
54: 'method' => 'setMash'
55: ),
56: );
57:
58: protected $complexPropertySets = array(
59: 'HOPS' => array(
60: 'tag' => 'HOP',
61: 'parser' => '\BeerXML\Parser\Hop',
62: 'method' => 'addHop'
63: ),
64: 'FERMENTABLES' => array(
65: 'tag' => 'FERMENTABLE',
66: 'parser' => '\BeerXML\Parser\Fermentable',
67: 'method' => 'addFermentable',
68: ),
69: 'MISCS' => array(
70: 'tag' => 'MISC',
71: 'parser' => '\BeerXML\Parser\Misc',
72: 'method' => 'addMisc',
73: ),
74: 'WATERS' => array(
75: 'tag' => 'WATER',
76: 'parser' => '\BeerXML\Parser\Water',
77: 'method' => 'addWater',
78: ),
79: 'YEASTS' => array(
80: 'tag' => 'YEAST',
81: 'parser' => '\BeerXML\Parser\Yeast',
82: 'method' => 'addYeast',
83: ),
84: 'MASH_STEPS' => array(
85: 'tag' => 'MASH_STEP',
86: 'parser' => '\BeerXML\Parser\MashStep',
87: 'method' => 'addMashStep',
88: ),
89: 'STYLES' => array(
90: 'tag' => 'STYLE',
91: 'parser' => '\BeerXML\Parser\Style',
92: 'method' => 'addSTyle'
93: ),
94: 'EQUIPMENTS' => array(
95: 'tag' => 'EQUIPMENT',
96: 'parser' => '\BeerXML\Parser\Equipment',
97: 'method' => 'addEquipment'
98: ),
99: 'MASHS' => array(
100: 'tag' => 'MASH',
101: 'parser' => '\BeerXML\Parser\MashProfile',
102: 'method' => 'addMash'
103: ),
104: );
105:
106: 107: 108:
109: public function setRecordFactory($recordFactory)
110: {
111: $this->recordFactory = $recordFactory;
112: }
113:
114: 115: 116:
117: public function setXmlReader($xmlReader)
118: {
119: $this->xmlReader = $xmlReader;
120: }
121:
122: 123: 124:
125: public function setXmlString($xmlStr)
126: {
127: $this->xmlReader = new \XMLReader();
128: $this->xmlReader->XML($xmlStr);
129: }
130:
131: 132: 133: 134:
135: public function parse()
136: {
137: $record = $this->createRecord();
138:
139: while ($this->tagName != $this->xmlReader->name || \XMLReader::END_ELEMENT != $this->xmlReader->nodeType) {
140: if (!@$this->xmlReader->read()) {
141: throw new BadData('Surprise end of file! Missing close tag <' . $this->tagName . '>');
142: };
143:
144: if ($this->xmlReader->isEmptyElement) {
145: continue;
146: }
147:
148: if (\XMLReader::ELEMENT == $this->xmlReader->nodeType) {
149: if (isset($this->simpleProperties[$this->xmlReader->name])) {
150: $method = $this->simpleProperties[$this->xmlReader->name];
151:
152: $record->{$method}($this->xmlReader->readString());
153: } elseif (isset($this->complexProperties[$this->xmlReader->name])) {
154: $this->setComplexProperty($record);
155: } elseif (isset($this->complexPropertySets[$this->xmlReader->name])) {
156: $this->setComplexPropertySet($record);
157: } else {
158: $this->otherElementEncountered($record);
159: }
160: }
161: }
162:
163: return $record;
164: }
165:
166: abstract protected function createRecord();
167:
168: 169: 170: 171: 172:
173: protected function otherElementEncountered($record)
174: {
175: }
176:
177: 178: 179: 180: 181: 182:
183: protected function setComplexPropertySet($record)
184: {
185:
186: $setTag = $this->xmlReader->name;
187: $setType = $this->complexPropertySets[$this->xmlReader->name];
188: $tag = $setType['tag'];
189: $parserClass = $setType['parser'];
190: $recordAdder = $setType['method'];
191: while ($setTag != $this->xmlReader->name || \XMLReader::END_ELEMENT != $this->xmlReader->nodeType) {
192: $this->xmlReader->read();
193:
194: if ($this->xmlReader->isEmptyElement) {
195: continue;
196: }
197:
198: if ($tag == $this->xmlReader->name && \XMLReader::ELEMENT == $this->xmlReader->nodeType) {
199: $recordParser = $this->createRecordParser($parserClass);
200: $complex = $recordParser->parse();
201:
202: $record->{$recordAdder}($complex);
203: }
204: }
205: }
206:
207: 208: 209: 210: 211:
212: protected function setComplexProperty($record)
213: {
214: $recordType = $this->complexProperties[$this->xmlReader->name];
215: $recordParser = $this->createRecordParser($recordType['parser']);
216: $complex = $recordParser->parse();
217: $method = $recordType['method'];
218:
219: $record->{$method}($complex);
220: }
221:
222: 223: 224: 225:
226: protected function createRecordParser($class)
227: {
228: $recordParser = new $class;
229:
230: $recordParser->setXmlReader($this->xmlReader);
231: $recordParser->setRecordFactory($this->recordFactory);
232: return $recordParser;
233: }
234: }
235:
236: