/** * Add a single column to the ContentType table. * * @param \Bolt\Storage\Database\Schema\Table\ContentType $tableObj * @param \Doctrine\DBAL\Schema\Table $table * @param string $fieldName * @param array $values * @param FieldManager $fieldManager */ private function addContentTypeTableColumn(ContentType $tableObj, Table $table, $fieldName, array $values, FieldManager $fieldManager) { if ($tableObj->isKnownType($values['type'])) { // Use loose comparison on true as 'true' in YAML is a string $addIndex = isset($values['index']) && (bool) $values['index'] === true; // Add the contenttype's specific fields $tableObj->addCustomFields($fieldName, $this->getContentTypeTableColumnType($values), $addIndex); } elseif ($handler = $fieldManager->getDatabaseField($values['type'])) { // Add template fields /** @var $handler \Bolt\Storage\Field\FieldInterface */ $table->addColumn($fieldName, $handler->getStorageType(), $handler->getStorageOptions()); } }
public function testAddingFetchingfields() { $field = $this->getMock('Bolt\\Storage\\Field\\Base', null, ['test', 'test.twig']); $manager = new Manager(); $manager->addField($field); $this->assertTrue($manager->has('test')); $this->assertEquals($field, $manager->getField('test')); $this->assertFalse($manager->getField('nonexistent')); $this->assertGreaterThan(5, $manager->fields()); }
public function testAddingFetchingfields() { /** @var Base $field */ $field = $this->getMockBuilder(Base::class)->setMethods(null)->setConstructorArgs(['test', 'test.twig'])->getMock(); $manager = new Manager(); $manager->addField($field); $this->assertTrue($manager->has('test')); $this->assertEquals($field, $manager->getField('test')); $this->assertFalse($manager->getField('nonexistent')); $this->assertGreaterThan(5, $manager->fields()); }
/** * Sanity checks for doubles in in contenttypes. */ public function checkConfig() { $slugs = []; foreach ($this->data['contenttypes'] as $key => $ct) { /** * Make sure any field that has a 'uses' parameter actually points to a field that exists. * * For example, this will show a notice: * entries: * name: Entries * singular_name: Entry * fields: * title: * type: text * class: large * slug: * type: slug * uses: name */ foreach ($ct['fields'] as $fieldname => $field) { // Verify that the contenttype doesn't try to add fields that are reserved. if ($fieldname != 'slug' && in_array($fieldname, $this->reservedFieldNames)) { $error = Trans::__('contenttypes.generic.reserved-name', ['%contenttype%' => $key, '%field%' => $fieldname]); $this->app['logger.flash']->error($error); return; } // Check 'uses'. If it's an array, split it up, and check the separate parts. We also need to check // for the fields that are always present, like 'id'. if (!empty($field['uses']) && is_array($field['uses'])) { foreach ((array) $field['uses'] as $useField) { if (!empty($field['uses']) && empty($ct['fields'][$useField]) && !in_array($useField, $this->reservedFieldNames)) { $error = Trans::__('contenttypes.generic.wrong-use-field', ['%contenttype%' => $key, '%field%' => $fieldname, '%uses%' => $useField]); $this->app['logger.flash']->error($error); return; } } } // Make sure the 'type' is in the list of allowed types if (!isset($field['type']) || !$this->fields->has($field['type'])) { $error = Trans::__('contenttypes.generic.no-proper-type', ['%contenttype%' => $key, '%field%' => $fieldname, '%type%' => $field['type']]); $this->app['logger.flash']->error($error); unset($ct['fields'][$fieldname]); } } // Keep a running score of used slugs. if (!isset($slugs[$ct['slug']])) { $slugs[$ct['slug']] = 0; } $slugs[$ct['slug']]++; if (!isset($slugs[$ct['singular_slug']])) { $slugs[$ct['singular_slug']] = 0; } if ($ct['singular_slug'] != $ct['slug']) { $slugs[$ct['singular_slug']]++; } } // Sanity checks for taxonomy.yml foreach ($this->data['taxonomy'] as $key => $taxo) { // Show some helpful warnings if slugs or keys are not set correctly. if ($taxo['slug'] != $key) { $error = Trans::__("The identifier and slug for '%taxonomytype%' are the not the same ('%slug%' vs. '%taxonomytype%'). Please edit taxonomy.yml, and make them match to prevent inconsistencies between database storage and your templates.", ['%taxonomytype%' => $key, '%slug%' => $taxo['slug']]); $this->app['logger.flash']->error($error); return; } } // if there aren't any other errors, check for duplicates across contenttypes. if (!$this->app['logger.flash']->has('error')) { foreach ($slugs as $slug => $count) { if ($count > 1) { $error = Trans::__("The slug '%slug%' is used in more than one contenttype. Please edit contenttypes.yml, and make them distinct.", ['%slug%' => $slug]); $this->app['logger.flash']->error($error); return; } } } }
/** * Sanity checks for doubles in in contenttypes. * * @return bool */ public function checkConfig() { $slugs = []; $passed = true; foreach ($this->data['contenttypes'] as $key => $ct) { // Make sure that there are no hyphens in the contenttype name, advise to change to underscores if (strpos($key, '-') !== false) { $error = Trans::__('contenttypes.generic.invalid-hyphen', ['%contenttype%' => $key]); $this->app['logger.flash']->error($error); $original = $this->data['contenttypes'][$key]; $key = str_replace('-', '_', strtolower(Str::makeSafe($key, true))); $this->data['contenttypes'][$key] = $original; $passed = false; } /** * Make sure any field that has a 'uses' parameter actually points to a field that exists. * * For example, this will show a notice: * entries: * name: Entries * singular_name: Entry * fields: * title: * type: text * class: large * slug: * type: slug * uses: name */ foreach ($ct['fields'] as $fieldname => $field) { // Verify that the contenttype doesn't try to add fields that are reserved. if ($fieldname != 'slug' && in_array($fieldname, $this->reservedFieldNames)) { $error = Trans::__('contenttypes.generic.reserved-name', ['%contenttype%' => $key, '%field%' => $fieldname]); $this->app['logger.flash']->danger($error); $passed = false; } // Check 'uses'. If it's an array, split it up, and check the separate parts. We also need to check // for the fields that are always present, like 'id'. if (!empty($field['uses']) && is_array($field['uses'])) { foreach ((array) $field['uses'] as $useField) { if (!empty($field['uses']) && empty($ct['fields'][$useField]) && !in_array($useField, $this->reservedFieldNames)) { $error = Trans::__('contenttypes.generic.wrong-use-field', ['%contenttype%' => $key, '%field%' => $fieldname, '%uses%' => $useField]); $this->app['logger.flash']->warning($error); $passed = false; } } } // Make sure that there are no hyphens in the field names, advise to change to underscores if (!isset($field['type']) || !$this->fields->has($field['type'])) { $error = Trans::__('contenttypes.generic.no-proper-type', ['%contenttype%' => $key, '%field%' => $fieldname, '%type%' => $field['type']]); $this->app['logger.flash']->warning($error); unset($ct['fields'][$fieldname]); $passed = false; } } /** * Make sure any contenttype that has a 'relation' defined points to a contenttype that exists. */ if (isset($ct['relations'])) { foreach ($ct['relations'] as $relKey => $relData) { // For BC we check if relation uses hyphen and re-map to underscores if (strpos($relKey, '-') !== false) { $newRelKey = str_replace('-', '_', strtolower(Str::makeSafe($relKey, true))); unset($this->data['contenttypes'][$key]['relations'][$relKey]); $this->data['contenttypes'][$key]['relations'][$newRelKey] = $relData; $relKey = $newRelKey; } if (!isset($this->data['contenttypes'][$relKey])) { $error = Trans::__('contenttypes.generic.invalid-relation', ['%contenttype%' => $key, '%relation%' => $relKey]); $this->app['logger.flash']->error($error); unset($this->data['contenttypes'][$key]['relations'][$relKey]); $passed = false; } } } // Keep a running score of used slugs. if (!isset($slugs[$ct['slug']])) { $slugs[$ct['slug']] = 0; } $slugs[$ct['slug']]++; if (!isset($slugs[$ct['singular_slug']])) { $slugs[$ct['singular_slug']] = 0; } if ($ct['singular_slug'] != $ct['slug']) { $slugs[$ct['singular_slug']]++; } } // Sanity checks for taxonomy.yml foreach ($this->data['taxonomy'] as $key => $taxo) { // Show some helpful warnings if slugs or keys are not set correctly. if ($taxo['slug'] != $key) { $error = Trans::__("The identifier and slug for '%taxonomytype%' are the not the same ('%slug%' vs. '%taxonomytype%'). Please edit taxonomy.yml, and make them match to prevent inconsistencies between database storage and your templates.", ['%taxonomytype%' => $key, '%slug%' => $taxo['slug']]); $this->app['logger.flash']->warning($error); $passed = false; } } // if there aren't any other errors, check for duplicates across contenttypes. if (!$this->app['logger.flash']->has('error')) { foreach ($slugs as $slug => $count) { if ($count > 1) { $error = Trans::__("The slug '%slug%' is used in more than one contenttype. Please edit contenttypes.yml, and make them distinct.", ['%slug%' => $slug]); $this->app['logger.flash']->warning($error); $passed = false; } } } return $passed && $this->checkTaxonomy(); }