1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
22:
23: namespace picon;
24:
25: 26: 27: 28: 29: 30: 31: 32: 33:
34: class MarkupLoader
35: {
36: 37: 38:
39: const MARKUP_RESOURCE_PREFIX = 'markup_';
40:
41: 42: 43: 44:
45: private static $instance;
46:
47: 48: 49: 50:
51: private static $extensions = array('html', 'htm');
52:
53: 54: 55:
56: private function __construct()
57: {
58:
59: }
60:
61: 62: 63: 64:
65: public static function get()
66: {
67: if(!isset(self::$instance))
68: {
69: self::$instance = new self();
70: }
71: return self::$instance;
72: }
73:
74: 75: 76: 77: 78:
79: public function loadMarkup(Component $component)
80: {
81: $name = get_class($component);
82: $fileSafeName = str_replace('\\', '_', $name);
83:
84: if(PiconApplication::get()->getProfile()->isCacheMarkup())
85: {
86: if(CacheManager::resourceExists(self::MARKUP_RESOURCE_PREFIX.$fileSafeName, CacheManager::APPLICATION_SCOPE))
87: {
88: return CacheManager::loadResource(self::MARKUP_RESOURCE_PREFIX.$fileSafeName, CacheManager::APPLICATION_SCOPE);
89: }
90: else
91: {
92: $markup = $this->internalLoadMarkup($name);
93: CacheManager::saveResource(self::MARKUP_RESOURCE_PREFIX.$fileSafeName, $markup, CacheManager::APPLICATION_SCOPE);
94: return $markup;
95: }
96: }
97: else
98: {
99: return $this->internalLoadMarkup($name);;
100: }
101: }
102:
103: private function internalLoadMarkup($className)
104: {
105: $reflection = new \ReflectionClass($className);
106: $fileInfo = new \SplFileInfo($reflection->getFileName());
107: $parser = new MarkupParser();
108:
109: foreach(self::$extensions as $extension)
110: {
111: $file = $fileInfo->getPath()."/".$reflection->getShortName().'.'.$extension;
112: if(file_exists($file))
113: {
114: return $this->completeMarkup($parser->parse($file), $className);
115: }
116: }
117: if(get_parent_class($className)!=false)
118: {
119: return $this->internalLoadMarkup(get_parent_class($className));
120: }
121: return null;
122: }
123:
124: private function completeMarkup($markup, $className)
125: {
126:
127: $head = $markup->getChildByName('head');
128:
129: if($head==null)
130: {
131: $html = $markup->getChildByName('html');
132: $body = $markup->getChildByName('body');
133: $head = new PiconTag('head');
134: $html->setChildren(array($head, $body));
135: }
136:
137: $extension = MarkupUtils::findPiconTag('extend', $markup);
138: if($extension!=null)
139: {
140: $parentMarkup = $this->internalLoadMarkup(get_parent_class($className));
141: if($parentMarkup==null)
142: {
143: throw new \MarkupNotFoundException(sprintf("Found picon:extend in markup for %s but there is no parent markup", $className));
144: }
145:
146: $child = $this->getChildTag($parentMarkup);
147: if($child==null)
148: {
149: throw new \MarkupNotFoundException(sprintf("Component %s has inherited markup from %s but the inherited markup does not contain a picon:child tag", $className, get_parent_class($className)));
150: }
151:
152: $childHead = $markup->getChildByName('picon:head');
153:
154: if($childHead!=null)
155: {
156: $head = $parentMarkup->getChildByName('head');
157: $head->addChild($childHead);
158: }
159:
160: $child->addChild($extension);
161: return $parentMarkup;
162: }
163:
164: return $markup;
165: }
166:
167: private function getChildTag($markup)
168: {
169: $child = MarkupUtils::findPiconTag('child', $markup);
170:
171: if($child==null)
172: {
173: return null;
174: }
175:
176: $existingExtension = MarkupUtils::findPiconTag('extend', $child);
177: if($existingExtension==null)
178: {
179: return $child;
180: }
181: else
182: {
183: return $this->getChildTag($existingExtension);
184: }
185: }
186: }
187:
188: ?>
189: