Skip to content

Commit

Permalink
Merge pull request #7 from ademarco/field-handlers
Browse files Browse the repository at this point in the history
Field handling implementation for API driver

Signed-off-by: Jonathan Hedstrom <[email protected]>
  • Loading branch information
jhedstrom committed Feb 20, 2015
1 parent 37fb2c7 commit 6fa9050
Show file tree
Hide file tree
Showing 21 changed files with 587 additions and 84 deletions.
7 changes: 7 additions & 0 deletions src/Drupal/Driver/BaseDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ public function roleDelete($rid) {
throw new UnsupportedDriverActionException($this->errorString('delete roles'), $this);
}

/**
* {@inheritDoc}
*/
public function isField($entity_type, $field_name) {
return FALSE;
}

/**
* Error printing exception
*
Expand Down
49 changes: 49 additions & 0 deletions src/Drupal/Driver/Cores/AbstractCore.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

/**
* @file
* Contains \Drupal\Driver\Cores\AbstractCore
*/

namespace Drupal\Driver\Cores;

use Symfony\Component\DependencyInjection\Container;

abstract class AbstractCore implements CoreInterface {

/**
* {@inheritDoc}
*/
public function getFieldHandler($entity_type, $field_name) {

$reflection = new \ReflectionClass($this);
$core_namespace = $reflection->getShortName();
$field_types = $this->getEntityFieldTypes($entity_type);
$camelized_type = Container::camelize($field_types[$field_name]);
$default_class = sprintf('\Drupal\Driver\Fields\%s\DefaultHandler', $core_namespace);
$class_name = sprintf('\Drupal\Driver\Fields\%s\%sHandler', $core_namespace, $camelized_type);
if (class_exists($class_name)) {
return new $class_name($entity_type, $field_name);
}
return new $default_class($entity_type, $field_name);
}

/**
* Given a entity, expand fields to match the format expected by entity_save().
*
* @param \stdClass $entity
* Entity object.
* @return \stdClass
* Entity object.
*/
protected function expandEntityFields($entity_type, \stdClass $entity) {

$field_types = $this->getEntityFieldTypes($entity_type);
foreach ($field_types as $field_name => $type) {
if (isset($entity->$field_name)) {
$entity->$field_name = $this->getFieldHandler($entity_type, $field_name)->expand($entity->$field_name);
}
}
}

}
29 changes: 29 additions & 0 deletions src/Drupal/Driver/Cores/CoreInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,33 @@ public function roleCreate(array $permissions);
*/
public function roleDelete($role_name);

/**
* Get FieldHandler class.
*
* @param $entity_type
* Entity type machine name.
* @param $field_name
* Field machine name.
* @return \Drupal\Driver\Fields\FieldHandlerInterface
*/
public function getFieldHandler($entity_type, $field_name);

/**
* Check if the specified field is an actual Drupal field.
*
* @param $entity_type
* @param $field_name
* @return boolean
*/
public function isField($entity_type, $field_name);

/**
* Return array of field types for the specified entity
* keyed by their field names.
*
* @param $entity_type
* @return array
*/
public function getEntityFieldTypes($entity_type);

}
113 changes: 31 additions & 82 deletions src/Drupal/Driver/Cores/Drupal7.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

use Drupal\Component\Utility\Random;
use Drupal\Driver\Exception\BootstrapException;
use Symfony\Component\DependencyInjection\Container;

/**
* Drupal 7 core.
*/
class Drupal7 implements CoreInterface {
class Drupal7 extends AbstractCore {
/**
* System path to the Drupal installation.
*
Expand Down Expand Up @@ -97,7 +98,7 @@ public function nodeCreate($node) {
$this->expandEntityProperties($node);

// Attempt to decipher any fields that may be specified.
$node = $this->expandEntityFields($node);
$this->expandEntityFields('node', $node);

// Set defaults that haven't already been set.
$defaults = clone $node;
Expand Down Expand Up @@ -135,7 +136,10 @@ public function userCreate(\stdClass $user) {
// hashed password.
$account = clone $user;

user_save($account, (array) $user);
// Attempt to decipher any fields that may be specified.
$this->expandEntityFields('user', $account);

user_save($account, (array) $account);

// Store UID.
$user->uid = $account->uid;
Expand Down Expand Up @@ -286,85 +290,6 @@ public function validateDrupalSite() {
}
}

/**
* Given a node object, expand fields to match the format expected by node_save().
*
* @param stdClass $entity
* Entity object.
* @param string $entityType
* Entity type, defaults to node.
* @param string $bundle
* Entity bundle.
*/
protected function expandEntityFields(\stdClass $entity, $entityType = 'node', $bundle = '') {
if ($entityType === 'node' && !$bundle) {
$bundle = $entity->type;
}

$new_entity = clone $entity;
foreach ($entity as $param => $value) {
if ($info = field_info_field($param)) {
foreach ($info['bundles'] as $type => $bundles) {
if ($type == $entityType) {
foreach ($bundles as $target_bundle) {
if ($bundle === $target_bundle) {
unset($new_entity->{$param});

// Use the first defined column. @todo probably breaks things.
$column_names = array_keys($info['columns']);
$column = array_shift($column_names);

// Special handling for date fields (start/end).
// @todo generalize this
if ('date' === $info['module']) {
// Dates passed in separated by a comma are start/end dates.
$dates = explode(',', $value);
$value = trim($dates[0]);
if (!empty($dates[1])) {
$column2 = array_shift($column_names);
$new_entity->{$param}[LANGUAGE_NONE][0][$column2] = trim($dates[1]);
}
$new_entity->{$param}[LANGUAGE_NONE][0][$column] = $value;
}
// Special handling for term references.
elseif ('taxonomy' === $info['module']) {
$terms = explode(',', $value);
$i = 0;
foreach ($terms as $term) {
$tid = taxonomy_get_term_by_name($term);
if (!$tid) {
throw new \Exception(sprintf("No term '%s' exists.", $term));
}

$new_entity->{$param}[LANGUAGE_NONE][$i][$column] = array_shift($tid)->tid;
$i++;
}
}

elseif (is_array($value)) {
foreach ($value as $key => $data) {
if (is_int($key) && (isset($value[$key+1]) || isset($value[$key-1]))) {
$new_entity->{$param}[LANGUAGE_NONE][$key] = $data;
} else {
$new_entity->{$param}[LANGUAGE_NONE][0][$key] = $data;
}
}
}


else {
$new_entity->{$param}[LANGUAGE_NONE][0][$column] = $value;
}
}
}
}
}
}
}

return $new_entity;
}

/**
* Given an entity object, expand any property fields to the expected structure.
*/
Expand Down Expand Up @@ -423,6 +348,9 @@ public function termCreate(\stdClass $term) {
throw new \Exception(sprintf('No "%s" vocabulary found.'));
}

// Attempt to decipher any fields that may be specified.
$this->expandEntityFields('taxonomy_term', $term);

// Protect against a failure from hook_taxonomy_term_insert() in pathauto.
$current_path = getcwd();
chdir(DRUPAL_ROOT);
Expand Down Expand Up @@ -471,4 +399,25 @@ public function getModuleList() {
return module_list();
}

/**
* {@inheritDoc}
*/
public function getEntityFieldTypes($entity_type) {
$return = array();
$fields = field_info_field_map();
foreach ($fields as $field_name => $field) {
if ($this->isField($entity_type, $field_name)) {
$return[$field_name] = $field['type'];
}
}
return $return;
}

/**
* {@inheritDoc}
*/
public function isField($entity_type, $field_name) {
$map = field_info_field_map();
return isset($map[$field_name]);
}
}
28 changes: 27 additions & 1 deletion src/Drupal/Driver/Cores/Drupal8.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

use Drupal\Component\Utility\Random;
use Drupal\Driver\Exception\BootstrapException;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\node\Entity\Node;
use Drupal\node\NodeInterface;
use Drupal\taxonomy\Entity\Term;

/**
* Drupal 8 core.
*/
class Drupal8 implements CoreInterface {
class Drupal8 extends AbstractCore {
/**
* System path to the Drupal installation.
*
Expand Down Expand Up @@ -94,6 +95,7 @@ public function nodeCreate($node) {
if (!isset($node->status)) {
$node->status = 1;
}
$this->expandEntityFields('node', $node);
$entity = entity_create('node', (array) $node);
$entity->save();

Expand Down Expand Up @@ -130,6 +132,7 @@ public function userCreate(\stdClass $user) {

// Clone user object, otherwise user_save() changes the password to the
// hashed password.
$this->expandEntityFields('user', $user);
$account = entity_create('user', (array) $user);
$account->save();

Expand Down Expand Up @@ -326,6 +329,7 @@ public function validateDrupalSite() {
*/
public function termCreate(\stdClass $term) {
$term->vid = $term->vocabulary_machine_name;
$this->expandEntityFields('taxonomy_term', $term);
$entity = Term::create((array) $term);
$entity->save();

Expand All @@ -348,4 +352,26 @@ public function getModuleList() {
return \Drupal::moduleHandler()->getModuleList();
}

/**
* {@inheritDoc}
*/
public function getEntityFieldTypes($entity_type) {
$return = array();
$fields = \Drupal::entityManager()->getFieldStorageDefinitions($entity_type);
foreach ($fields as $field_name => $field) {
if ($this->isField($entity_type, $field_name)) {
$return[$field_name] = $field->getType();
}
}
return $return;
}

/**
* {@inheritDoc}
*/
public function isField($entity_type, $field_name) {
$fields = \Drupal::entityManager()->getFieldStorageDefinitions($entity_type);
return (isset($fields[$field_name]) && $fields[$field_name] instanceof FieldStorageConfig);
}

}
8 changes: 8 additions & 0 deletions src/Drupal/Driver/DriverInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,12 @@ public function roleCreate(array $permissions);
*/
public function roleDelete($rid);

/**
* Check if the specified field is an actual Drupal field.
*
* @param $entity_type
* @param $field_name
* @return boolean
*/
public function isField($entity_type, $field_name);
}
8 changes: 7 additions & 1 deletion src/Drupal/Driver/DrupalDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ public function getSubDriverPaths() {

// Active profile
// @todo

return $paths;
}

Expand Down Expand Up @@ -276,4 +275,11 @@ public function roleDelete($rid) {
$this->getCore()->roleDelete($rid);
}

/**
* {@inheritDoc}
*/
public function isField($entity_type, $field_name) {
return $this->getCore()->isField($entity_type, $field_name);
}

}
29 changes: 29 additions & 0 deletions src/Drupal/Driver/Fields/Drupal7/AbstractHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

/**
* @file
* Contains \Drupal\Driver\Fields\Drupal7\AbstractFieldHandler
*/

namespace Drupal\Driver\Fields\Drupal7;

use Drupal\Driver\Fields\FieldHandlerInterface;

abstract class AbstractHandler implements FieldHandlerInterface {

/**
* @var
*/
protected $field_info = array();

/**
* Get field instance information.
*
* @param $field_name
* @return mixed
*/
public function __construct($entity_type, $field_name) {
$this->field_info = field_info_field($field_name);
}

}
Loading

0 comments on commit 6fa9050

Please sign in to comment.