This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Merge pull request #5 from slashrsm/type_plugins

Media type plugins
  • Loading branch information...
slashrsm committed Sep 16, 2014
2 parents 621252d + 603dee8 commit ecfafc7510ac6d8eb4997bf107060dc05cd57c93
@@ -8,9 +8,14 @@ media_entity.bundle.*:
label:
type: label
label: 'Label'
type:
type: label
label: 'Type'
description:
type: text
label: 'Description'
type:
type: string
label: 'Type plugin ID'
type_configuration:
type: media_entity.bundle.type.[%type]
field_map:
type: mapping
label: 'Field map'
@@ -0,0 +1,25 @@
<?php
/**
* @file
* Hooks related to media entity and it's plugins.
*/
/**
* @addtogroup hooks
* @{
*/
/**
* Alter the information provided in \Drupal\media_entity\Annotation\MediaType.
*
* @param $types
* The array of type plugins, keyed on the machine-readable name.
*/
function hook_media_entity_type_info_alter(&$types) {
$types['youtube']['label'] = t('Youtube rocks!');
}
/**
* @} End of "addtogroup hooks".
*/
@@ -0,0 +1,4 @@
services:
plugin.manager.media_entity.type:
class: Drupal\media_entity\MediaTypeManager
parent: default_plugin_manager
@@ -1,7 +1,9 @@
id: image
label: Images
type: image
description: 'Images of pretty puppies.'
type: 'generic'
type_configuration: { }
status: true
langcode: en
dependencies: { }
field_map: { }
@@ -0,0 +1,48 @@
<?php
/**
* @file
* Contains \Drupal\media_entity\Annotation\MediaType.
*/
namespace Drupal\media_entity\Annotation;
use Drupal\Component\Annotation\Plugin;
/**
* Defines an media entity type plugin annotation object.
*
* @see hook_media_entity_type_info_alter()
*
* @Annotation
*/
class MediaType extends Plugin {
/**
* The plugin ID.
*
* @var string
*/
public $id;
/**
* The human-readable name of the type.
*
* @ingroup plugin_translatable
*
* @var \Drupal\Core\Annotation\Translation
*/
public $label;
/**
* A brief description of the plugin.
*
* This will be shown when adding or configuring this display.
*
* @ingroup plugin_translatable
*
* @var \Drupal\Core\Annotation\Translation (optional)
*/
public $description = '';
}
@@ -195,6 +195,20 @@ public function preSave(EntityStorageInterface $storage) {
if (!$this->get('revision_uid')->entity) {
$this->set('revision_uid', $this->getPublisherId());
}
// Try to set fields provided by type plugin and mapped in bundle
// configuration.
$bundle = $this->entityManager()->getStorage('media_bundle')->load($this->bundle());
foreach ($bundle->field_map as $source_field => $destination_field) {
// Only save value in entity field if empty. Do not overwrite existing data.
// @TODO We might modify that in the future but let's leave it like this
// for now.
if ($this->{$destination_field} && $this->{$destination_field}->isEmpty() && ($value = $bundle->getType()->getField($this, $source_field))) {
$property_name = $this->{$destination_field}->first()->mainPropertyName();
$this->{$destination_field}->first()->{$property_name} = $value;
}
}
}
/**
@@ -8,6 +8,8 @@
namespace Drupal\media_entity\Entity;
use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
use Drupal\Core\Entity\EntityWithPluginBagsInterface;
use Drupal\Core\Plugin\DefaultSinglePluginBag;
use Drupal\media_entity\MediaBundleInterface;
use Drupal\media_entity\MediaInterface;
@@ -30,17 +32,15 @@
* bundle_of = "media",
* entity_keys = {
* "id" = "id",
* "label" = "label",
* "type" = "type",
* "uuid" = "uuid"
* "label" = "label"
* },
* links = {
* "edit-form" = "media.bundle_edit",
* "delete-form" = "media.bundle_delete_confirm"
* }
* )
*/
class MediaBundle extends ConfigEntityBundleBase implements MediaBundleInterface {
class MediaBundle extends ConfigEntityBundleBase implements MediaBundleInterface, EntityWithPluginBagsInterface {
/**
* The machine name of this media bundle.
@@ -57,18 +57,39 @@ class MediaBundle extends ConfigEntityBundleBase implements MediaBundleInterface
public $label;
/**
* The type of this media bundle.
* A brief description of this media bundle.
*
* @var string
*/
public $type;
public $description;
/**
* A brief description of this media bundle.
* The type plugin id.
*
* @var string
*/
public $description;
public $type = 'generic';
/**
* The type plugin configuration.
*
* @var array
*/
public $type_configuration = array();
/**
* Type plugin bag.
*
* @var \Drupal\Core\Plugin\DefaultSinglePluginBag
*/
protected $typeBag;
/**
* Field map. Fields provided by type plugin to be stored as entity fields.
*
* @var array
*/
public $field_map = array();
/**
* {@inheritdoc}
@@ -80,8 +101,10 @@ public function id() {
/**
* {@inheritdoc}
*/
public function type() {
return $this->type;
public function getPluginBags() {
return array(
'type' => $this->typeBag(),
);
}
/**
@@ -105,4 +128,25 @@ public static function exists($id) {
public function getDescription() {
return $this->description;
}
/**
* {@inheritdoc}
*/
public function getType() {
return $this->typeBag()->get($this->type);
}
/**
* Returns type plugin bag.
*
* @return \Drupal\Core\Plugin\DefaultSinglePluginBag
* The tag plugin bag.
*/
protected function typeBag() {
if (!$this->typeBag) {
$this->typeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.media_entity.type'), $this->type, $this->type_configuration);
}
return $this->typeBag;
}
}
@@ -10,6 +10,7 @@
use Drupal\Core\Entity\EntityForm;
use Drupal\Component\Utility\String;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
/**
* Form controller for node type forms.
@@ -21,6 +22,7 @@ class MediaBundleForm extends EntityForm {
*/
public function form(array $form, FormStateInterface $form_state) {
$form = parent::form($form, $form_state);
/** @var \Drupal\media_entity\MediaBundleInterface $bundle */
$bundle = $this->entity;
if ($this->operation == 'add') {
$form['#title'] = String::checkPlain($this->t('Add media bundle'));
@@ -51,21 +53,46 @@ public function form(array $form, FormStateInterface $form_state) {
'#description' => t('A unique machine-readable name for this media bundle.'),
);
$form['type'] = array(
'#title' => t('Type'),
'#type' => 'textfield',
'#default_value' => $bundle->type(),
'#description' => t('The type of this media bundle e.g. image, video, audio.'),
'#required' => TRUE,
'#size' => 30,
);
$form['description'] = array(
'#title' => t('Description'),
'#type' => 'textarea',
'#default_value' => $bundle->getDescription(),
'#description' => t('Describe this media bundle. The text will be displayed on the <em>Add new media</em> page.'),
);
$plugins = \Drupal::service('plugin.manager.media_entity.type')->getDefinitions();
$options = array();
foreach ($plugins as $plugin => $definition) {
$options[$plugin] = $definition['label'];
}
$form['type'] = array(
'#type' => 'select',
'#title' => t('Type provider'),
'#default_value' => $bundle->getType()->getPluginId(),
'#options' => $options,
'#description' => t('Media type provider plugin that is responsible for additional logic related to this media.'),
);
$form['type_configuration'] = array(
'#type' => 'fieldset',
'#title' => t('Type provider configuration'),
'#tree' => TRUE,
);
foreach ($plugins as $plugin => $definition) {
$plugin_configuration = $bundle->getType()->getPluginId() == $plugin ? $bundle->type_configuration : array();
$form['type_configuration'][$plugin] = array(
'#type' => 'container',
'#states' => array(
'visible' => array(
':input[name="type"]' => array('value' => $plugin),
),
),
);
$form['type_configuration'][$plugin] += \Drupal::service('plugin.manager.media_entity.type')->createInstance($plugin, $plugin_configuration)->settingsForm($this->entity);
}
return parent::form($form, $form_state);
}
@@ -87,6 +114,9 @@ public function save(array $form, FormStateInterface $form_state) {
$bundle = $this->entity;
$bundle->id = trim($bundle->id());
// Use type configuration for the plugin that was chosen.
$bundle->type_configuration = empty($bundle->type_configuration[$bundle->type]) ? array() : $bundle->type_configuration[$bundle->type];
$status = $bundle->save();
$t_args = array('%name' => $bundle->label());
@@ -14,14 +14,6 @@
*/
interface MediaBundleInterface extends ConfigEntityInterface {
/**
* Returns the type of the media bundle.
*
* @return string
* Returns the type of the media bundle.
*/
public function type();
/**
* Returns the label.
*
@@ -51,4 +43,12 @@ public static function exists($id);
* Returns the Media bundle description.
*/
public function getDescription();
/**
* Returns the media type plugin.
*
* @return \Drupal\media_entity\MediaTypeInterface
* The type.
*/
public function getType();
}
@@ -248,4 +248,25 @@ public function delete(array $form, FormStateInterface $form_state) {
);
}
/**
* {@inheritdoc}
*/
public function validate(array $form, FormStateInterface $form_state) {
parent::validate($form, $form_state);
/** @var \Drupal\media_entity\MediaInterface $entity */
$entity = $this->buildEntity($form, $form_state);
/** @var \Drupal\media_entity\MediaBundleInterface $bundle */
$bundle = $this->entityManager->getStorage('media_bundle')->load($entity->bundle());
if ($type = $bundle->getType()) {
try {
$type->validate($entity);
}
catch (MediaTypeException $e) {
$form_state->setErrorByName($e->getElement(), $e->getMessage());
}
}
}
}
Oops, something went wrong.

0 comments on commit ecfafc7

Please sign in to comment.