Overview

Namespaces

  • DcGeneral
    • Clipboard
    • Contao
      • Callback
      • Compatibility
      • DataDefinition
        • Definition
      • Dca
        • Builder
          • Legacy
        • Definition
        • Palette
        • Populator
      • Event
      • View
        • Contao2BackendView
          • Event
    • Controller
    • Data
    • DataDefinition
      • Builder
      • Definition
        • Properties
        • View
          • Panel
      • ModelRelationship
      • Palette
        • Builder
          • Event
        • Condition
          • Palette
          • Property
    • EnvironmentPopulator
    • Event
    • Exception
    • Factory
      • Event
    • Panel
    • View
      • Event

Classes

  • LegacyPalettesParser
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: /**
  3:  * PHP version 5
  4:  *
  5:  * @package    generalDriver
  6:  * @author     Christian Schiffler <c.schiffler@cyberspectrum.de>
  7:  * @author     Stefan Heimes <stefan_heimes@hotmail.com>
  8:  * @author     Tristan Lins <tristan.lins@bit3.de>
  9:  * @copyright  The MetaModels team.
 10:  * @license    LGPL.
 11:  * @filesource
 12:  */
 13: 
 14: namespace DcGeneral\Contao\Dca\Palette;
 15: 
 16: use DcGeneral\DataDefinition\Palette\Condition\Palette\DefaultPaletteCondition;
 17: use DcGeneral\DataDefinition\Palette\Condition\Palette\PaletteConditionChain;
 18: use DcGeneral\DataDefinition\Palette\Condition\Palette\PaletteConditionInterface;
 19: use DcGeneral\DataDefinition\Palette\Condition\Palette\PropertyValueCondition as PalettePropertyValueCondition;
 20: use DcGeneral\DataDefinition\Palette\Condition\Palette\PropertyTrueCondition as PalettePropertyTrueCondition;
 21: use DcGeneral\DataDefinition\Palette\Condition\Property\PropertyTrueCondition;
 22: use DcGeneral\DataDefinition\Palette\Condition\Property\PropertyValueCondition;
 23: use DcGeneral\DataDefinition\Palette\Legend;
 24: use DcGeneral\DataDefinition\Palette\Palette;
 25: use DcGeneral\DataDefinition\Palette\PaletteCollection;
 26: use DcGeneral\DataDefinition\Palette\PaletteCollectionInterface;
 27: use DcGeneral\DataDefinition\Palette\PaletteInterface;
 28: use DcGeneral\DataDefinition\Palette\Property;
 29: use DcGeneral\DataDefinition\Palette\PropertyInterface;
 30: 
 31: /**
 32:  * Class LegacyPalettesParser.
 33:  *
 34:  * This class parses the palettes from a legacy DCA into the palette collection definitions being used in DcGeneral.
 35:  *
 36:  * @package DcGeneral\Contao\Dca\Palette
 37:  */
 38: class LegacyPalettesParser
 39: {
 40:     /**
 41:      * Parse the palette and sub palette array and create a complete palette collection.
 42:      *
 43:      * @param array(string => string)         $palettes    The palettes from the DCA.
 44:      *
 45:      * @param array(string => string)         $subpalettes The sub palettes from the DCA [optional].
 46:      *
 47:      * @param PaletteCollectionInterface|null $collection  The palette collection to populate [optional].
 48:      *
 49:      * @return PaletteCollectionInterface
 50:      */
 51:     public function parse(array $palettes, array $subpalettes = array(), PaletteCollectionInterface $collection = null)
 52:     {
 53:         if (isset($palettes['__selector__']))
 54:         {
 55:             $selectorFieldNames = $palettes['__selector__'];
 56:             unset($palettes['__selector__']);
 57:         }
 58:         else
 59:         {
 60:             $selectorFieldNames = array();
 61:         }
 62: 
 63:         $subPaletteProperties = $this->parseSubpalettes($subpalettes, $selectorFieldNames);
 64: 
 65:         return $this->parsePalettes(
 66:             $palettes,
 67:             $subPaletteProperties,
 68:             $selectorFieldNames,
 69:             $collection
 70:         );
 71:     }
 72: 
 73:     /**
 74:      * Parse the given palettes.
 75:      *
 76:      * @param array(string => string)    $palettes             The array of palettes, e.g.
 77:      *                                                         <code>array('default' => '{title_legend},title')</code>.
 78:      *
 79:      * @param array(string => string)    $subPaletteProperties Mapped array from subpalette [optional].
 80:      *
 81:      * @param array                      $selectorFieldNames   List of names of the properties to be used as selector
 82:      *                                                         [optional].
 83:      *
 84:      * @param PaletteCollectionInterface $collection           The palette collection to populate [optional].
 85:      *
 86:      * @return PaletteCollectionInterface
 87:      */
 88:     public function parsePalettes(
 89:         array $palettes,
 90:         array $subPaletteProperties = array(),
 91:         array $selectorFieldNames = array(),
 92:         PaletteCollectionInterface $collection = null
 93:     )
 94:     {
 95:         if (!$collection)
 96:         {
 97:             $collection = new PaletteCollection();
 98:         }
 99: 
100:         if (isset($palettes['__selector__']))
101:         {
102:             $selectorFieldNames = array_merge($selectorFieldNames, $palettes['__selector__']);
103:             $selectorFieldNames = array_unique($selectorFieldNames);
104:             unset($palettes['__selector__']);
105:         }
106: 
107:         foreach ($palettes as $selector => $fields)
108:         {
109:             // Fields list must be a string.
110:             if (!is_string($fields))
111:             {
112:                 continue;
113:             }
114: 
115:             if ($collection->hasPaletteByName($selector))
116:             {
117:                 $palette = $collection->getPaletteByName($selector);
118:                 $this->parsePalette(
119:                     $selector,
120:                     $fields,
121:                     $subPaletteProperties,
122:                     $selectorFieldNames,
123:                     $palette
124:                 );
125:             }
126:             else {
127:                 $palette = $this->parsePalette(
128:                     $selector,
129:                     $fields,
130:                     $subPaletteProperties,
131:                     $selectorFieldNames
132:                 );
133:                 $collection->addPalette($palette);
134:             }
135:         }
136: 
137:         return $collection;
138:     }
139: 
140:     /**
141:      * Parse a single palette.
142:      *
143:      * @param string                             $paletteSelector      The selector for the palette.
144:      *
145:      * @param string                             $fields               The fields contained within the palette.
146:      *
147:      * @param array(string => PropertyInterface) $subPaletteProperties The sub palette properties [optional].
148:      *
149:      * @param array(string)                      $selectorFieldNames   The names of all properties being used as
150:      *                                                                 selectors [optional].
151:      *
152:      * @param PaletteInterface                   $palette              The palette to be populated [optional].
153:      *
154:      * @return Palette
155:      */
156:     public function parsePalette(
157:         $paletteSelector,
158:         $fields,
159:         array $subPaletteProperties = array(),
160:         array $selectorFieldNames = array(),
161:         PaletteInterface $palette = null
162:     )
163:     {
164:         if (!$palette)
165:         {
166:             $palette = new Palette();
167:             $palette->setName($paletteSelector);
168:         }
169: 
170:         $condition = $this->createPaletteCondition($paletteSelector, $selectorFieldNames);
171:         $palette->setCondition($condition);
172: 
173:         // We ignore the difference between field set (separated by ";") and fields (separated by ",").
174:         $fields = preg_split('~[;,]~', $fields);
175:         $fields = array_map('trim', $fields);
176:         $fields = array_filter($fields);
177: 
178:         $legend = null;
179: 
180:         foreach ($fields as $field)
181:         {
182:             // TODO what about :hide? this is currently not supported by LegendInterface.
183:             if (preg_match('~^\{(.*?)(_legend)?(:hide)?\}$~', $field, $matches))
184:             {
185:                 $name = $matches[1];
186:                 if ($palette->hasLegend($name))
187:                 {
188:                     $legend = $palette->getLegend($name);
189:                 }
190:                 else
191:                 {
192:                     $legend = new Legend($matches[1]);
193:                     $palette->addLegend($legend);
194:                 }
195:             }
196:             else {
197:                 // Fallback for incomplete palettes without legend,
198:                 // Create an empty legend.
199:                 if (!$legend)
200:                 {
201:                     $name = 'unnamed';
202:                     if ($palette->hasLegend($name))
203:                     {
204:                         $legend = $palette->getLegend($name);
205:                     }
206:                     else
207:                     {
208:                         $legend = new Legend($matches[1]);
209:                         $palette->addLegend($legend);
210:                     }
211:                 }
212: 
213:                 // Add the current field to the legend.
214:                 $property = new Property($field);
215:                 $legend->addProperty($property);
216: 
217:                 // Add sub palette fields to the legend.
218:                 if (isset($subPaletteProperties[$field]))
219:                 {
220:                     foreach ($subPaletteProperties[$field] as $property)
221:                     {
222:                         $legend->addProperty(clone $property);
223:                     }
224:                 }
225:             }
226:         }
227: 
228:         return $palette;
229:     }
230: 
231:     /**
232:      * Parse the palette selector and create the corresponding condition.
233:      *
234:      * @param string $paletteSelector    Create the condition for the selector.
235:      *
236:      * @param array  $selectorFieldNames The property names to be used as selectors.
237:      *
238:      * @return PaletteConditionInterface
239:      */
240:     public function createPaletteCondition($paletteSelector, array $selectorFieldNames)
241:     {
242:         if ($paletteSelector == 'default')
243:         {
244:             return new DefaultPaletteCondition();
245:         }
246: 
247:         // Legacy fallback, try to split on $selectors with optimistic suggestion of values.
248:         if (strpos($paletteSelector, '|') === false)
249:         {
250:             foreach ($selectorFieldNames as $selectorFieldName)
251:             {
252:                 $paletteSelector = str_replace(
253:                     $selectorFieldName,
254:                     '|' . $selectorFieldName . '|',
255:                     $paletteSelector
256:                 );
257:             }
258:         }
259: 
260:         // Extended mode, split selectors and values with "|".
261:         $paletteSelectorParts = explode('|', $paletteSelector);
262:         $paletteSelectorParts = array_map('trim', $paletteSelectorParts);
263:         $paletteSelectorParts = array_filter($paletteSelectorParts);
264: 
265:         $condition = new PaletteConditionChain();
266: 
267:         foreach ($paletteSelectorParts as $paletteSelectorPart)
268:         {
269:             // The part is a property name (checkbox like selector).
270:             if (in_array($paletteSelectorPart, $selectorFieldNames))
271:             {
272:                 $condition->addCondition(
273:                     new PalettePropertyTrueCondition($paletteSelectorPart)
274:                 );
275:             }
276:             // The part is a value (but which?) (select box like selector).
277:             else
278:             {
279:                 $orCondition = new PaletteConditionChain(array(), PaletteConditionChain::OR_CONJUNCTION);
280: 
281:                 foreach ($selectorFieldNames as $selectorFieldName)
282:                 {
283:                     $orCondition->addCondition(
284:                         new PalettePropertyValueCondition(
285:                             $selectorFieldName,
286:                             $paletteSelectorPart
287:                         )
288:                     );
289:                 }
290: 
291:                 $condition->addCondition($orCondition);
292:             }
293:         }
294: 
295:         return $condition;
296:     }
297: 
298:     /**
299:      * Parse the sub palettes and return the properties for each selector property.
300:      *
301:      * @param array $subpalettes        The sub palettes to parse.
302:      *
303:      * @param array $selectorFieldNames Names of the selector properties [optional].
304:      *
305:      * @return array(string => PropertyInterface[])
306:      */
307:     public function parseSubpalettes(array $subpalettes, array $selectorFieldNames = array())
308:     {
309:         $properties = array();
310: 
311:         foreach ($subpalettes as $subPaletteSelector => $childFields)
312:         {
313:             // Child fields list must be a string.
314:             if (!is_string($childFields))
315:             {
316:                 continue;
317:             }
318: 
319:             $selectorFieldName = $this->createSubpaletteSelectorFieldName($subPaletteSelector, $selectorFieldNames);
320: 
321:             $properties[$selectorFieldName] = $this->parseSubpalette(
322:                 $subPaletteSelector,
323:                 $childFields,
324:                 $selectorFieldNames
325:             );
326:         }
327: 
328:         return $properties;
329:     }
330: 
331:     /**
332:      * Parse the list of sub palette fields into an array of properties.
333:      *
334:      * @param string $subPaletteSelector The selector in use.
335:      *
336:      * @param string $childFields        List of the properties for the sub palette.
337:      *
338:      * @param array  $selectorFieldNames List of the selector properties [optional].
339:      *
340:      * @return PropertyInterface[]
341:      */
342:     public function parseSubpalette($subPaletteSelector, $childFields, array $selectorFieldNames = array())
343:     {
344:         $childFields = explode(',', $childFields);
345:         $childFields = array_map('trim', $childFields);
346: 
347:         $condition = $this->createSubpaletteCondition($subPaletteSelector, $selectorFieldNames);
348: 
349:         $properties = array();
350: 
351:         foreach ($childFields as $childField)
352:         {
353:             $property = new Property($childField);
354:             $property->setVisibleCondition(clone $condition);
355:             $properties[] = $property;
356:         }
357: 
358:         return $properties;
359:     }
360: 
361:     /**
362:      * Translate a sub palette selector into the real name of a property.
363:      *
364:      * This method supports the following cases for the sub palette selector:
365:      *
366:      * Case 1: the sub palette selector contain a combination of "property name" + '_' + value
367:      *         in which we require that the "property name" is contained within $selectorFieldNames.
368:      *         In this cases a select/radio sub palette is in place.
369:      *
370:      * Case 2: the sub palette selector is only a "property name", the value is then implicated to be true.
371:      *         In this cases a checkbox sub palette is in place.
372:      *
373:      * @param string $subPaletteSelector The selector being evaluated.
374:      *
375:      * @param array  $selectorFieldNames The names of the properties to be used as selectors [optional].
376:      *
377:      * @return string
378:      */
379:     public function createSubpaletteSelectorFieldName($subPaletteSelector, array $selectorFieldNames = array())
380:     {
381:         $selectorValues     = explode('_', $subPaletteSelector);
382:         $selectorFieldName  = array_shift($selectorValues);
383:         $selectorValueCount = count($selectorValues);
384:         while ($selectorValueCount)
385:         {
386:             if (in_array($selectorFieldName, $selectorFieldNames))
387:             {
388:                 break;
389:             }
390:             $selectorFieldName .= '_' . array_shift($selectorValues);
391:         }
392: 
393:         return $selectorFieldName;
394:     }
395: 
396:     /**
397:      * Parse the sub palette selector and create the corresponding condition.
398:      *
399:      * This method supports the following cases for the sub palette selector:
400:      *
401:      * Case 1: the sub palette selector contain a combination of "property name" + '_' + value
402:      *         in which we require that the "property name" is contained within $selectorFieldNames.
403:      *         In this cases a select/radio sub palette is in place.
404:      *
405:      * Case 2: the sub palette selector is only a "property name", the value is then implicated to be true.
406:      *         In this cases a checkbox sub palette is in place.
407:      *
408:      * @param string $subPaletteSelector The selector being evaluated.
409:      *
410:      * @param array  $selectorFieldNames The names of the properties to be used as selectors [optional].
411:      *
412:      * @return PropertyTrueCondition|PropertyValueCondition|null
413:      */
414:     public function createSubpaletteCondition($subPaletteSelector, array $selectorFieldNames = array())
415:     {
416:         $condition = null;
417: 
418:         // Try to find a select value first (case 1).
419:         $selectorValues     = explode('_', $subPaletteSelector);
420:         $selectorFieldName  = array_shift($selectorValues);
421:         $selectorValueCount = count($selectorValues);
422:         while ($selectorValueCount)
423:         {
424:             if (in_array($selectorFieldName, $selectorFieldNames))
425:             {
426:                 $condition = new PropertyValueCondition($selectorFieldName, implode('_', $selectorValues));
427:                 break;
428:             }
429:             $selectorFieldName .= '_' . array_shift($selectorValues);
430:         }
431: 
432:         // If case 1 was not successful, try implicitly case 2 must apply.
433:         if (!$condition)
434:         {
435:             $condition = new PropertyTrueCondition($subPaletteSelector);
436:         }
437: 
438:         return $condition;
439:     }
440: }
441: 
contao-community-alliance/dc-general API documentation generated by ApiGen 2.8.0