private function repeaterHydrate($record, $app) { $contentTypeName = $record->contenttype['slug']; $contentType = $app['config']->get('contenttypes/' . $contentTypeName); $values = $this->localeValues; $localeSlug = $app['translate.slug']; if (isset($values[$localeSlug . 'data'])) { $localeData = json_decode($values[$localeSlug . 'data'], true); foreach ($localeData as $key => $value) { if ($key === 'templatefields') { $templateFields = $app['config']->get('theme/templatefields/' . $record['template'] . '/fields'); foreach ($templateFields as $key => $field) { if ($field['type'] === 'repeater') { $localeData = json_decode($value[$key], true); $originalMapping = null; $originalMapping[$key]['fields'] = $templateFields[$key]['fields']; $originalMapping[$key]['type'] = 'repeater'; $mapping = $app['storage.metadata']->getRepeaterMapping($originalMapping); $repeater = new RepeatingFieldCollection($app['storage'], $mapping); $repeater->setName($key); foreach ($localeData as $subValue) { $repeater->addFromArray($subValue); } $record['templatefields'][$key] = $repeater; } } } if (isset($contentType['fields'][$key]) && $contentType['fields'][$key]['type'] === 'repeater') { /** * Hackish fix until #5533 gets fixed, after that the * following four (4) lines can be replaced with * "$record[$key]->clear();" */ $originalMapping[$key]['fields'] = $contentType['fields'][$key]['fields']; $originalMapping[$key]['type'] = 'repeater'; $mapping = $app['storage.metadata']->getRepeaterMapping($originalMapping); $record[$key] = new RepeatingFieldCollection($app['storage'], $mapping); foreach ($value as $subValue) { $record[$key]->addFromArray($subValue); } } } } }
/** * Normalize step ensures that we have correctly hydrated objects at the collection * and entity level. * * @param $entity */ public function normalize($entity) { $key = $this->mapping['fieldname']; $accessor = 'get' . ucfirst($key); $outerCollection = $entity->{$accessor}(); $newVal = []; if (!$outerCollection instanceof RepeatingFieldCollection) { $collection = new RepeatingFieldCollection($this->em); $collection->setName($key); if (is_array($outerCollection)) { foreach ($outerCollection as $group => $fields) { if (is_array($fields)) { $collection->addFromArray($fields, $group); } } } $setter = 'set' . ucfirst($key); $entity->{$setter}($collection); } }
/** * Set a ContentType record's values. * * @param array $values */ public function setValues(array $values) { // Since Bolt 1.4, we use 'ownerid' instead of 'username' in the DB tables. If we get an array that has an // empty 'ownerid', attempt to set it from the 'username'. In $this->setValue the user will be set, regardless // of ownerid is an 'id' or a 'username'. if (empty($values['ownerid']) && !empty($values['username'])) { $values['ownerid'] = $values['username']; unset($values['username']); } foreach ($values as $key => $value) { if ($key !== 'templatefields') { $this->setValue($key, $value); } } // If default status is set in contentttype. if (empty($this->values['status']) && isset($this->contenttype['default_status'])) { $this->values['status'] = $this->contenttype['default_status']; } $serializedFieldTypes = ['geolocation', 'imagelist', 'image', 'file', 'filelist', 'video', 'select', 'templateselect', 'checkbox', 'repeater']; // Check if the values need to be unserialized, and pre-processed. foreach ($this->values as $key => $value) { if (in_array($this->fieldtype($key), $serializedFieldTypes) || $key === 'templatefields') { if (!empty($value) && is_string($value) && (substr($value, 0, 2) === 'a:' || $value[0] === '[' || $value[0] === '{')) { try { $unserdata = Lib::smartUnserialize($value); } catch (\Exception $e) { $unserdata = false; } if ($unserdata !== false) { $this->values[$key] = $unserdata; } } } if ($this->fieldtype($key) === 'video' && is_array($this->values[$key]) && !empty($this->values[$key]['url'])) { $video = $this->values[$key]; // update the HTML, according to given width and height if (!empty($video['width']) && !empty($video['height'])) { $video['html'] = preg_replace("/width=(['\"])([0-9]+)(['\"])/i", 'width=${1}' . $video['width'] . '${3}', $video['html']); $video['html'] = preg_replace("/height=(['\"])([0-9]+)(['\"])/i", 'height=${1}' . $video['height'] . '${3}', $video['html']); } $responsiveclass = 'responsive-video'; // See if it's widescreen or not. if (!empty($video['height']) && $video['width'] / $video['height'] > 1.76) { $responsiveclass .= ' widescreen'; } if (strpos($video['url'], 'vimeo') !== false) { $responsiveclass .= ' vimeo'; } $video['responsive'] = sprintf('<div class="%s">%s</div>', $responsiveclass, $video['html']); // Mark them up as Twig_Markup. $video['html'] = new \Twig_Markup($video['html'], 'UTF-8'); $video['responsive'] = new \Twig_Markup($video['responsive'], 'UTF-8'); $this->values[$key] = $video; } if ($this->fieldtype($key) === 'repeater' && is_array($this->values[$key]) && !$this->isRootType) { $originalMapping = null; $originalMapping[$key]['fields'] = $this->contenttype['fields'][$key]['fields']; $originalMapping[$key]['type'] = 'repeater'; $mapping = $this->app['storage.metadata']->getRepeaterMapping($originalMapping); $repeater = new RepeatingFieldCollection($this->app['storage'], $mapping); $repeater->setName($key); foreach ($this->values[$key] as $subValue) { $repeater->addFromArray($subValue); } $this->values[$key] = $repeater; } if ($this->fieldtype($key) === 'date' || $this->fieldtype($key) === 'datetime') { if ($this->values[$key] === '') { $this->values[$key] = null; } } } // Template fields need to be done last // As the template has to have been selected if ($this->isRootType) { if (empty($values['templatefields'])) { $this->setValue('templatefields', []); } else { $this->setValue('templatefields', $values['templatefields']); } } }