Skip to content
Open
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,18 @@ This module's sole purpose is to help simplify creating custom bundlable, transl

We have tried to move as much code as possible into the content entity base module so only the entity definition is required for yoru custom entity module.

You can get started with this module by copying the tests/modules/ceb_test module and start renaming with search/replace. Note: There is not that much in the module though.
You can get started with this module by copying the tests/modules/ceb_test module and start renaming with search/replace or use [drupal console](https://github.com/hechoendrupal/DrupalConsole) to genereate a custom entity.

@todo Add Drupal console support to this module.
This is currently a pre-release version but has been moderately tested with Drupal 8.0.3.

This is currently a pre-release version but has been moderately tested with Drupal 8.0.3.
### Dependencies ###

1. Entity API: https://www.drupal.org/project/entity

### Drupal console ###

Console support is provided in a secondary module (**console_ceb**).

Usage: `console generate:entity:ceb --module foo_module --entity-class FooEntity --entity-name foo_content --label "Foo Content"`

**Notes:*** The console chain command does work with the `generate:entity:ceb` command because the necessary templates are not found.
7 changes: 7 additions & 0 deletions console_ceb/config/translations/console.en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
command:
console_ceb:
generate:
'entity:ceb':
description: 'Generate a new (Content Entity Base) content entity'
questions:
entity-class: 'Class?'
5 changes: 5 additions & 0 deletions console_ceb/console_ceb.info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: Console CEB
type: module
description: Provides Drupal Console integration for the CEB module.
core: 8.x
package: Drupal console
53 changes: 53 additions & 0 deletions console_ceb/src/Command/GenerateEntityCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
/**
* @file
* Contains \Drupal\console_ceb\Command\GenerateEntityCommand.
*/

namespace Drupal\console_ceb\Command;

use Drupal\Console\Command\Generate\EntityCommand;
use Drupal\console_ceb\Generator\EntityGenerator;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

/**
* Class GenerateEntityCommand.
*
* @package Drupal\console_ceb
*/
class GenerateEntityCommand extends EntityCommand {

/**
* {@inheritdoc}
*/
protected function configure() {
$this->setEntityType('EntityContent');
$this->setCommandName('generate:entity:ceb');
parent::configure();
}

/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$module = $input->getOption('module');
$entity_class = $input->getOption('entity-class');
$entity_name = $input->getOption('entity-name');
$label = $input->getOption('label');

$bundle_entity_name = $entity_name . '_type';

// Use the generator to create the entity files from the template files.
$this
->getGenerator()
->generate($module, $entity_name, $entity_class, $label, $bundle_entity_name);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should also check whether this is an existing entity or not.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea.

}

protected function createGenerator() {
return new EntityGenerator();
}
}
204 changes: 204 additions & 0 deletions console_ceb/src/Generator/EntityGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
<?php
/**
* @file
* Contains \Drupal\console_ceb\Generator\EntityGenerator.
*/

namespace Drupal\console_ceb\Generator;

use Drupal\Console\Generator\EntityContentGenerator;

/**
* Handles generating the files required for a Content Entity Base entity.
*
* Generates:
*
* 1. module.permissions.yml
* 2. module.links.menu.yml
* 3. module.links.action.yml
* 4. module.links.task.yml
* 5. module.page.inc
* 6. templates/entity.html.twig
* 7. templates/entity-content-add-list.html.twig
* 8. src/Entity/EntityClass.php
* 9. src/Entity/Access/EntityClassPermissions.php
*
* @package Drupal\console_ceb\Generator
*/
class EntityGenerator extends EntityContentGenerator {
/**
* Generator Entity.
*
* @param string $module Module name
* @param string $entity_name Entity machine name
* @param string $entity_class Entity class name
* @param string $label Entity label
* @param string $bundle_entity_type (Config) entity type acting as bundle
*/
public function generate($module, $entity_name, $entity_class, $label, $bundle_entity_type = null) {

// Get the module, entity and template paths.
$module_path = $this->getSite()->getModulePath($module);
$entity_path = $this->getSite()->getEntityPath($module);
$template_path = $this->getSite()->getTemplatePath($module);
$module_filename = "{$module_path}/{$module}.module";
$entity_hyphenated = str_replace('_', '-', $entity_name);


// Use these parameters for content entity creation.
$parameters = [
'module' => $module,
'entity_name' => $entity_name,
'entity_hyphenated' => $entity_hyphenated,
'entity_class' => $entity_class,
'label' => $label,
'bundle_entity_type' => $bundle_entity_type,
];

/**
* Create the yml files.
*/
$this->renderFile(
'module/permissions-entity-ceb.yml.twig',
"{$module_path}/{$module}.permissions.yml",
$parameters,
FILE_APPEND
);

$this->renderFile(
'module/links.menu-entity-ceb.yml.twig',
"{$module_path}/{$module}.links.menu.yml",
$parameters,
FILE_APPEND
);

$this->renderFile(
'module/links.task-entity-ceb.yml.twig',
"{$module_path}/{$module}.links.task.yml",
$parameters,
FILE_APPEND
);

$this->renderFile(
'module/links.action-entity-ceb.yml.twig',
"{$module_path}/{$module}.links.action.yml",
$parameters,
FILE_APPEND
);

/**
* Create the permissions class.
*/
$this->renderFile(
'module/src/Entity/Access/permissions.php.twig',
"{$entity_path}/Access/{$entity_class}Permissions.php",
$parameters + [
'class_name' => $entity_class.'Permissions',
]
);

/**
* Create the content entity plugin.
*/
$this->renderFile(
'module/src/Entity/entity-ceb-content.php.twig',
"{$entity_path}/{$entity_class}.php",
$parameters
);

/**
* Create the content entity's template files.
*/
$this->renderFile(
'module/entity-content-page.php.twig',
"{$module_path}/{$entity_name}.page.inc",
$parameters
);

$this->renderFile(
'module/templates/entity-html.twig',
"{$template_path}/{$entity_name}.html.twig",
$parameters
);

if ($bundle_entity_type) {
$bundle_entity_hyphenated = str_replace('_', '-', $entity_name);
$this->renderFile(
'module/templates/entity-with-bundle-content-add-list-html.twig',
"{$template_path}/{$bundle_entity_hyphenated}-content-add-list.html.twig",
$parameters
);

// Check for hook_theme() in module file and warn ...
if (file_exists($module_filename) && preg_match("/function\\s+{$module}_theme/", file_get_contents($module_filename)) !== 0) {
echo "================
Warning:
================
It looks like you have a hook_theme already declared!
Please manually merge the two hook_theme() implementations in {$module_filename}!
";
} else {

$this->renderFile(
'module/src/Entity/entity-content-with-bundle.theme.php.twig',
$module_filename,
$parameters,
FILE_APPEND
);
}

/**
* Compose the bundle parameters.
*/
$bundle_entity_class = "{$entity_class}Type";
$bundle_label = "{$label} type";
$bundle_parameters = [
'module' => $module,
'entity_name' => $bundle_entity_type,
'entity_hyphenated' => $bundle_entity_hyphenated,
'entity_class' => $bundle_entity_class,
'label' => $bundle_label,
'bundle_of' => $entity_name,
];

/**
* Render the bundle entity files.
*/
$this->renderFile(
'module/config/schema/entity.schema.yml.twig',
"{$module_path}" . "/config/schema/{$bundle_entity_type}.schema.yml",
$bundle_parameters
);

$this->renderFile(
'module/links.menu-entity-config.yml.twig',
"{$module_path}" . "/{$module}.links.menu.yml",
$bundle_parameters,
FILE_APPEND
);

$this->renderFile(
'module/links.action-entity.yml.twig',
"{$module_path}/{$module}.links.action.yml",
$bundle_parameters,
FILE_APPEND
);

$this->renderFile(
'module/src/Entity/entity-ceb-bundle.php.twig',
"{$entity_path}/{$bundle_entity_class}.php",
$bundle_parameters
);
}

$content = $this->getRenderHelper()->render(
'module/src/Entity/entity-content.theme.php.twig',
$parameters
);

if ($this->isLearning()) {
echo 'Add this to your hook_theme:'.PHP_EOL;
echo $content;
}
}
}
9 changes: 9 additions & 0 deletions console_ceb/templates/module/links.action-entity-ceb.yml.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Definition for {{ label }} menu links.

entity.{{ entity_name }}.add_form:
route_name: entity.{{ entity_name }}.add_page
title: 'Add {{ label }}'
appears_on:
- entity.{{ entity_name }}.collection
- entity.{{ entity_name }}.canonical

12 changes: 12 additions & 0 deletions console_ceb/templates/module/links.menu-entity-ceb.yml.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Definition for {{ label }} menu items.

entity.{{ entity_name }}.collection:
title: '{{ label }}'
route_name: entity.{{ entity_name }}.collection
description: 'List {{ label }} content'
parent: system.admin_content

{{ entity_name }}.add_page:
title: 'Add {{ label }}'
route_name: entity.{{ entity_name }}.add_page

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Definition for {{ label }} menu items.

entity.{{ entity_name }}.collection:
title: '{{ label }}'
route_name: entity.{{ entity_name }}.collection
description: 'Manage {{ label }} (bundles)'
parent: system.admin_structure
weight: 99

22 changes: 22 additions & 0 deletions console_ceb/templates/module/links.task-entity-ceb.yml.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Definition for {{ label }} menu tasks.
entity.{{ entity_name }}.canonical:
route_name: entity.{{ entity_name }}.canonical
base_route: entity.{{ entity_name }}.canonical
title: 'View'

entity.{{ entity_name }}.edit_form:
route_name: entity.{{ entity_name }}.edit_form
base_route: entity.{{ entity_name }}.canonical
title: 'Edit'

entity.{{ entity_name }}.delete_form:
route_name: entity.{{ entity_name }}.delete_form
base_route: entity.{{ entity_name }}.canonical
title: 'Delete'
weight: 10

entity.{{ entity_name }}.collection:
route_name: entity.{{ entity_name }}.collection
base_route: system.admin_content
title: '{{ label }} list'

3 changes: 3 additions & 0 deletions console_ceb/templates/module/permissions-entity-ceb.yml.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
permission_callbacks:
- \Drupal\{{ module }}\Entity\Access\{{ entity_class }}Permissions::entityPermissions

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{% extends "base/class.php.twig" %}

{% block file_path %}
Drupal\{{module}}\Entity\Access\{{ class_name }}.
{% endblock %}

{% block namespace_class %}
namespace Drupal\{{module}}\Entity\Access;
{% endblock %}

{% block use_class %}
use Drupal\content_entity_base\Entity\Access\EntityBasePermissions;
use Drupal\Core\Entity\ContentEntityTypeInterface;
{% endblock %}

{% block class_declaration %}
/**
* Class {{ class_name }}.
* Defines a class containing permission callbacks.
* @package Drupal\{{ module }}\Entity\Access
*/
class {{ class_name }} extends EntityBasePermissions {% endblock %}
{% block class_methods %}

/**
* {@inheritdoc}
*
* @todo Leverage https://www.drupal.org/node/2652684
*/
public function entityPermissions(ContentEntityTypeInterface $entity_type = NULL) {
return parent::entityPermissions(\Drupal::entityTypeManager()->getDefinition('{{ entity_name }}'));
}
{% endblock %}
Loading