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: class Localizer
34: {
35: const EXTENSION = '.properties';
36: const PROPERTIES_CACHE_NAME = 'localizer_properties';
37:
38: private $component;
39: private $properties;
40:
41: private function __construct(Component $component)
42: {
43: $this->component = $component;
44: $page = $component->getPage()==null?"":get_class($component->getPage());
45: $resourceName = self::PROPERTIES_CACHE_NAME.'_'.$page.'_'.$component->getComponentPath();
46: if(CacheManager::resourceExists($resourceName, CacheManager::APPLICATION_SCOPE))
47: {
48: $this->properties = CacheManager::loadResource($resourceName, CacheManager::APPLICATION_SCOPE);
49: }
50: else
51: {
52: $this->properties = $this->getProperties($this->component);
53: CacheManager::saveResource($resourceName, $this->properties, CacheManager::APPLICATION_SCOPE);
54: }
55: }
56:
57: public static function get(Component $component)
58: {
59: if($component->getParent()==null && !($component instanceof WebPage))
60: {
61: trigger_error('It is not safe to rely on the localizer until the component hierarchy is complete', E_USER_WARNING);
62: }
63:
64: return new self($component);
65: }
66:
67: private function getProperties(Component $component)
68: {
69: $target = $component;
70: $properties = array();
71:
72: while($target!=null)
73: {
74: $reflection = new \ReflectionClass($target);
75:
76: while($reflection!=null)
77: {
78: $fileInfo = new \SplFileInfo($reflection->getFileName());
79: $fileName = $fileInfo->getPath()."/".$reflection->getShortName().self::EXTENSION;
80: if(file_exists($fileName))
81: {
82: $loaded = $this->loadProperties($fileName);
83: foreach($loaded as $name => $value)
84: {
85: if(!array_key_exists($name, $properties))
86: {
87: $properties[$name] = $value;
88: }
89: }
90: }
91: $reflection = $reflection->getParentClass();
92: }
93: $target = $target->getParent();
94: }
95: return $properties;
96: }
97:
98: private function loadProperties($fileName)
99: {
100: $properties = array();
101: $fileHandle = fopen($fileName, 'r');
102: while (!feof($fileHandle))
103: {
104: $raw = fgets($fileHandle, 4096);
105: $pair = explode('=', $raw);
106: if(count($pair)==2)
107: {
108: $name = trim($pair[0]);
109: $value = trim($pair[1]);
110: $properties[$name] = $value;
111: }
112: }
113: fclose($fileHandle);
114: return $properties;
115: }
116:
117: 118: 119: 120: 121: 122: 123:
124: public function getString($key, $model = null)
125: {
126: $key = str_replace(Component::PATH_SEPERATOR, '.', $this->component->getComponentPath()).$key;
127: $string = null;
128: if($model!=null && !($model instanceof Model))
129: {
130: throw new \InvalidArgumentException(sprintf("Localizer::getString() expects argument 2 to be a Model"));
131: }
132: $string = $this->internalGetString($key);
133:
134: if($string!=null && $model!=null)
135: {
136: $string = $this->interpolate($string, $model);
137: }
138:
139: return $string;
140: }
141:
142: private function internalGetString($key)
143: {
144: if(array_key_exists($key, $this->properties))
145: {
146: return $this->properties[$key];
147: }
148: else
149: {
150: $keyHierarchy = explode('.', $key);
151:
152: if(count($keyHierarchy)>1)
153: {
154: unset($keyHierarchy[0]);
155: $lesserKey = implode('.', $keyHierarchy);
156: return $this->internalGetString($lesserKey);
157: }
158: }
159: }
160:
161:
162: 163: 164: 165: 166:
167: private function interpolate($string, Model $model)
168: {
169: $object = $model->getModelObject();
170:
171: if(is_object($object))
172: {
173: $reflection = new \ReflectionClass($object);
174: foreach($reflection->getProperties() as $property)
175: {
176: $property->setAccessible(true);
177: $name = $property->getName();
178: $value = $property->getValue($object);
179:
180: if(is_array($value))
181: {
182: $string = $this->interpolate($string, new ArrayModel($value));
183: }
184: else if(is_object($value))
185: {
186: throw new \UnsupportedOperationException('Recursive interpolation not supported');
187: }
188: else
189: {
190: $string = str_replace("\${".$name."}", $value, $string);
191: }
192: }
193: }
194: else if(is_array($object))
195: {
196: foreach($object as $key => $value)
197: {
198: $string = str_replace("\${".$key."}", $value, $string);
199: }
200: }
201: return $string;
202: }
203: }
204:
205: ?>
206: