1: <?php
2:
3: /**
4: * TODO: License
5: * TODO: How how handle access constraints. My idea would be to check in the
6: * constructor and throw an exception. The application then should catch
7: * the exception and handle it.
8: */
9:
10: namespace Mapbender\CoreBundle\Component;
11:
12: use Mapbender\CoreBundle\Entity\Element as Entity;
13: use Symfony\Component\DependencyInjection\ContainerInterface;
14: use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
15:
16: /**
17: * Base class for all Mapbender elements.
18: *
19: * This class defines all base methods and required instance methods to
20: * implement an Mapbender3 element.
21: *
22: * @author Christian Wygoda
23: */
24: abstract class Element
25: {
26:
27: /**
28: * Application
29: * @var Application An application object
30: */
31: protected $application;
32:
33: /**
34: * Container
35: * @var ContainterInterface The container
36: */
37: protected $container;
38:
39: /**
40: * Entity
41: * @var Entity The configuration storage entity
42: */
43: protected $entity;
44:
45: /**
46: * The constructor. Every element needs an application to live within and
47: * the container to do useful things.
48: *
49: * @param Application $application The application object
50: * @param ContainerInterface $container The container object
51: */
52: public function __construct(Application $application,
53: ContainerInterface $container, Entity $entity)
54: {
55: $this->application = $application;
56: $this->container = $container;
57: $this->entity = $entity;
58: }
59:
60: /* * ***********************************************************************
61: * *
62: * Class metadata *
63: * *
64: * *********************************************************************** */
65:
66: /**
67: * Returns the element class title
68: *
69: * This is primarily used in the manager backend when a list of available
70: * elements is given.
71: *
72: * @return string
73: */
74: static public function getClassTitle()
75: {
76: throw new \RuntimeException('getClassTitle needs to be implemented');
77: }
78:
79: /**
80: * Returns the element class description.
81: *
82: * This is primarily used in the manager backend when a list of available
83: * elements is given.
84: *
85: * @return string
86: */
87: static public function getClassDescription()
88: {
89: throw new \RuntimeException('getClassDescription needs to be implemented');
90: }
91:
92: /**
93: * Returns the element class tags.
94: *
95: * These tags are used in the manager backend to quickly filter the list
96: * of available elements.
97: *
98: * @return array
99: */
100: static public function getClassTags()
101: {
102: return array();
103: }
104:
105: /**
106: * Returns the default element options.
107: *
108: * You should specify all allowed options here with their default value.
109: *
110: * @return array
111: */
112: static public function getDefaultConfiguration()
113: {
114: return array();
115: }
116:
117: /* * ***********************************************************************
118: * *
119: * Configuration entity handling *
120: * *
121: * *********************************************************************** */
122:
123: /**
124: * Get a configuration value by path.
125: *
126: * Get the configuration value or null if the path is not defined. If you
127: * ask for an path which has children, the configuration array with these
128: * children will be returned.
129: *
130: * Configuration paths are lists of parameter keys seperated with a slash
131: * like "targets/map".
132: *
133: * @param string $path The configuration path to retrieve.
134: * @return mixed
135: */
136: final public function get($path)
137: {
138: throw new \RuntimeException('NIY get ' . $path . ' ' . get_class($this));
139: }
140:
141: /**
142: * Set a configuration value by path.
143: *
144: * @param string $path the configuration path to set
145: * @param mixed $value the value to set
146: */
147: final public function set($path, $value)
148: {
149: throw new \RuntimeException('NIY set');
150: }
151:
152: /**
153: * Get the configuration entity.
154: *
155: * @return object $entity
156: */
157: public function getEntity()
158: {
159: return $this->entity;
160: }
161:
162: /* * ***********************************************************************
163: * *
164: * Shortcut functions for leaner Twig templates *
165: * *
166: * *********************************************************************** */
167:
168: /**
169: * Get the element ID
170: *
171: * @return string
172: */
173: public function getId()
174: {
175: return $this->entity->getId();
176: }
177:
178: /**
179: * Get the element title
180: *
181: * @return string
182: */
183: public function getTitle()
184: {
185: return $this->entity->getTitle();
186: }
187:
188: /**
189: * Get the element description
190: *
191: * @return string
192: */
193: public function getDescription()
194: {
195: return $this->entity->getDescription();
196: }
197:
198: /* * ***********************************************************************
199: * *
200: * Frontend stuff *
201: * *
202: * *********************************************************************** */
203:
204: /**
205: * Render the element HTML fragment.
206: *
207: * @return string
208: */
209: abstract public function render();
210:
211: /**
212: * Get the element assets.
213: *
214: * Returns an array of references to asset files of the given type.
215: * Assets are grouped by css and javascript.
216: * References can either be filenames/path which are searched for in the
217: * Resources/public directory of the element's bundle or assetic references
218: * indicating the bundle to search in:
219: *
220: * array(
221: * 'foo.css'),
222: * '@MapbenderCoreBundle/Resources/public/foo.css'));
223: *
224: * @return array
225: */
226: public function getAssets()
227: {
228: return array();
229: }
230:
231: /**
232: * Get the publicly exposed configuration, usually directly derived from
233: * the configuration field of the configuration entity. If you, for
234: * example, store passwords in your element configuration, you should
235: * override this method to return a cleaned up version of your
236: * configuration which can safely be exposed in the client.
237: *
238: * @return array
239: */
240: public function getConfiguration()
241: {
242: // $configuration = $this->entity->getConfiguration();
243:
244: $configuration = $this->entity->getConfiguration();
245: // $config = $this->entity->getConfiguration();
246: // //@TODO merge recursive $this->entity->getConfiguration() and $this->getDefaultConfiguration()
247: // $def_configuration = $this->getDefaultConfiguration();
248: // $configuration = array();
249: // foreach ($def_configuration as $key => $val) {
250: // if(isset($config[$key])){
251: // $configuration[$key] = $config[$key];
252: // }
253: // }
254: return $configuration;
255: }
256:
257: /**
258: * Get the function name of the JavaScript widget for this element. This
259: * will be called to initialize the element.
260: *
261: * @return string
262: */
263: abstract public function getWidgetName();
264:
265: /**
266: * Handle element Ajax requests.
267: *
268: * Do your magic here.
269: *
270: * @param string $action The action to perform
271: * @return Response
272: */
273: public function httpAction($action)
274: {
275: throw new NotFoundHttpException('This element has no Ajax handler.');
276: }
277:
278: /* * ***********************************************************************
279: * *
280: * Backend stuff *
281: * *
282: * *********************************************************************** */
283:
284: /**
285: * Get the element configuration form type.
286: *
287: * Override this method to provide a custom configuration form instead of
288: * the default YAML form.
289: *
290: * @return Symfony\Component\FormTypeInterface
291: */
292: public static function getType()
293: {
294: return null;
295: }
296:
297: /**
298: * Get the form template to use.
299: *
300: * @return string
301: */
302: public static function getFormTemplate()
303: {
304: return null;
305: }
306:
307: /**
308: * Get the form assets.
309: *
310: * @return array
311: */
312: public static function getFormAssets()
313: {
314: return array(
315: 'js' => array(),
316: 'css' => array());
317: }
318:
319: /**
320: * Merges the default configuration array and the configuration array
321: *
322: * @param array $default the default configuration of an element
323: * @param array $main the configuration of an element
324: * @param array $result the result configuration
325: * @return array the result configuration
326: */
327: public static function mergeArrays($default, $main, $result)
328: {
329: foreach($main as $key => $value)
330: {
331: if($value === null)
332: {
333: $result[$key] = null;
334: } else if(is_array($value))
335: {
336: if(isset($default[$key]))
337: {
338: $result[$key] = Element::mergeArrays($default[$key],
339: $main[$key], array());
340: } else
341: {
342: $result[$key] = $main[$key];
343: }
344: } else
345: {
346: $result[$key] = $value;
347: }
348: }
349: if($default !== null && is_array($default))
350: {
351: foreach($default as $key => $value)
352: {
353: if(!isset($result[$key])
354: || (isset($result[$key])
355: && $result[$key] === null
356: && $value !== null))
357: {
358: $result[$key] = $value;
359: }
360: }
361: }
362: return $result;
363: }
364:
365: /**
366: * Post save
367: */
368: public function postSave()
369: {
370:
371: }
372:
373: }
374:
375: