eventbrite_one_way_sync-1.0.0/modules/eventbrite_one_way_sync_node/src/EventNode/NodeFactory.php
modules/eventbrite_one_way_sync_node/src/EventNode/NodeFactory.php
<?php namespace Drupal\eventbrite_one_way_sync_node\EventNode; use Drupal\Component\Serialization\Json; use Drupal\Core\Entity\EntityInterface; use Drupal\eventbrite_one_way_sync\EventbriteEvent\EventbriteEventValidInterface; use Drupal\eventbrite_one_way_sync\Utilities\CommonUtilities; use Drupal\eventbrite_one_way_sync_node\Utilities\DependencyInjection; use Drupal\node\NodeInterface; /** * Obtain node objects. */ class NodeFactory implements NodeFactoryInterface { use DependencyInjection; use CommonUtilities; /** * {@inheritdoc} */ public function entityToNodeAndStruct(EntityInterface $entity, array &$struct, string &$eventbrite_account_label) : NodeInterface|null { if ($entity->getEntityType()->id() != 'node') { return NULL; } // At this point we have a node. Just make sure. if ($entity instanceof NodeInterface) { foreach ($this->nodeConfig()->getFieldMapping() as $account_label => $info) { if ($entity->getType() == $info['node_type']) { $field_values = $entity->get($info['id_field'])->getValue(); if (isset($field_values[0]['value']) && substr($field_values[0]['value'], 0, strlen($account_label . ':')) == $account_label . ':') { // We have a hit. $eventbrite_account_label = $account_label; $struct = $this->nodeStruct($entity, $info['struct_field']); return $entity; } } } } // This entity is not an Eventbrite node. return NULL; } /** * Given a node and field, return a struct. * * @param \Drupal\node\NodeInterface $node * A node. * @param string $field_name * A field name. * * @return array * A struct. */ public function nodeStruct(NodeInterface $node, string $field_name) : array { $field_values = $node->get($field_name)->getValue(); $ret = []; if (isset($field_values[0]['value'])) { $ret = Json::decode($field_values[0]['value']); } return is_array($ret) ? $ret : []; } /** * {@inheritdoc} */ public function getOrCreateNode(EventbriteEventValidInterface $event) : EventNodeInterface { $account = $event->remoteId()->eventbriteAccountName(); $node_type = $this->nodeConfig()->nodeType($account); $id_field = $this->nodeConfig()->idField($account); $candidate = $this->fetchSingleNode($node_type, $id_field, $event->remoteId()->toString()); if (!$candidate) { $candidate = $this->createNode($node_type, $id_field, $event->remoteId()->toString()); } return new EventNode($candidate, $event); } /** * {@inheritdoc} */ public function resaveAllNodes(string $eventbrite_account_label, int $max = PHP_INT_MAX) { $nids = $this->getAllNids($eventbrite_account_label, $max); print_r('We found ' . count($nids) . ' nids' . PHP_EOL); $nodes = $this->entityTypeManager()->getStorage('node')->loadMultiple($nids); foreach ($nodes as $node) { $node->save(); } } /** * Get all nids the related to an Eventbrite account. * * @param string $eventbrite_account_label * An Eventbrite account label, for example "default". * @param int $max * The maximum number of nodes to save. Useful for testing. */ public function getAllNids(string $eventbrite_account_label, int $max = PHP_INT_MAX) : array { $this->assertNonEmptyString($eventbrite_account_label, 'Eventbrite account label cannot be empty'); $node_type = $this->nodeConfig()->nodeType($eventbrite_account_label); $id_field = $this->nodeConfig()->idField($eventbrite_account_label); $like = $this->connection()->escapeLike($eventbrite_account_label . ':') . '%'; print_r('We will attempt to load a maximum of ' . PHP_INT_MAX . ' nodes with ' . $id_field . ' LIKE ' . $like . ':' . PHP_EOL); $query = $this->drupalEntityQuery('node'); $query->accessCheck(FALSE); $query->condition('type', $node_type); $query->condition($id_field, $like, 'LIKE'); $query->range(0, $max); return $query->execute(); } /** * {@inheritdoc} */ public function deleteAllNodes(string $eventbrite_account_label, int $max = PHP_INT_MAX) { $nids = $this->getAllNids($eventbrite_account_label, $max); print_r('We found ' . count($nids) . ' nids' . PHP_EOL); $nodes = $this->entityTypeManager()->getStorage('node')->loadMultiple($nids); $this->entityTypeManager()->getStorage('node')->delete($nodes); print_r('We have deleted these ' . count($nids) . ' nodes:' . PHP_EOL); print_r($nids); } /** * Get a single node if it exists. * * @param string $node_type * A node type such as event. * @param string $id_field * An ID field such as field_eventbrite_id. * @param string $remoteId * A remote ID such as default:series:123. * * @return \Drupal\node\NodeInterface|null * A Drupal node if it exists, NULL otherwise. */ public function fetchSingleNode(string $node_type, string $id_field, string $remoteId) : NodeInterface|null { $this->assertNonEmptyString($node_type, 'Node type cannot be empty'); $this->assertNonEmptyString($id_field, 'ID field cannot be empty'); $this->assertNonEmptyString($remoteId, 'Remote ID cannot be empty'); $query = $this->drupalEntityQuery('node'); $query->accessCheck(FALSE); $query->condition('type', $node_type); $query->condition($id_field, $remoteId); // We want there to be 0 or 1, but if we get 2 we'll fail. $query->range(0, 2); $nids = $query->execute(); $nodes = $this->entityTypeManager()->getStorage('node')->loadMultiple($nids); if (count($nodes) == 1) { return array_pop($nodes); } if (count($nodes) == 0) { return NULL; } throw new \Exception('There is more than one node with ' . $id_field . ' set to ' . $remoteId . '; there should not be; please check nodes ' . implode(', ', $nids)); } /** * Create a new node. * * @param string $node_type * A node type such as event. * @param string $id_field * An ID field such as field_eventbrite_id. * @param string $remoteId * A remote ID such as default:series:123. * * @return \Drupal\node\NodeInterface * A Drupal node. */ public function createNode(string $node_type, string $id_field, string $remoteId) : NodeInterface { $this->assertNonEmptyString($node_type, 'Node type cannot be empty'); $this->assertNonEmptyString($id_field, 'ID field cannot be empty'); $this->assertNonEmptyString($remoteId, 'Remote ID cannot be empty'); $node = $this->entityTypeManager()->getStorage('node')->create([ 'title' => 'New Event', 'type' => $node_type, $id_field => $remoteId, ]); $node->save(); return $node; } }