public function deleteExistingObject(NodeInterface $node, Context $context, $dirtyAllowed = false)
 {
     /* @var $node EntityNode */
     $bundle = $node->getName();
     $exists = (int) db_query("SELECT 1 FROM {node} WHERE type = :type", array(':type' => $bundle));
     if ($exists) {
         $context->logDataloss(sprintf("%s: node type has nodes", $node->getPath()));
     }
     node_type_delete($bundle);
 }
 public function deleteExistingObject(NodeInterface $node, Context $context, $dirtyAllowed = false)
 {
     /* @var $node FieldInstanceNode */
     $existing = field_info_instance($node->getEntityType(), $node->getName(), $node->getBundle());
     if (!$existing) {
         $context->logWarning(sprintf("%s: does not exists", $node->getPath()));
         return false;
     }
     field_delete_instance($existing);
 }
 /**
  * Return the filter name depending on the tree structure
  *
  * @param NodeInterface $node
  * @param Context $context
  * @return array|mixed|string
  */
 protected function getFormatName(NodeInterface $node, Context $context)
 {
     if ($node->hasChild('name')) {
         $value = $node->getChild('name')->getValue();
         if (!is_string($value)) {
             $context->logCritical(sprintf("%s: name attribute is not a string", $node->getPath()));
         }
         return $value;
     }
     return $node->getName();
 }
 public function deleteExistingObject(NodeInterface $node, Context $context, $dirtyAllowed = false)
 {
     /* @var $node EntityNode */
     $bundle = $node->getBundle();
     $vocabulary = taxonomy_vocabulary_machine_name_load($bundle);
     $exists = (int) db_query("SELECT 1 FROM {taxonomy_term_data} d WHERE d.vid = :vid", [':vid' => $vocabulary->vid]);
     if ($exists) {
         $context->logDataloss(sprintf("%s: taxonomy vocabulary has terms", $node->getPath()));
     }
     taxonomy_vocabulary_delete($vocabulary->vid);
 }
Example #5
0
 /**
  * {@inheritdoc}
  */
 public function synchronize(NodeInterface $node, Context $context, $dirtyAllowed = false)
 {
     /* @var $node \USync\AST\Drupal\MenuNode */
     $object = ['menu_name' => $node->getName()];
     if ($node->hasChild('name')) {
         $object['title'] = (string) $node->getChild('name')->getValue();
     }
     if ($node->hasChild('description')) {
         $object['description'] = (string) $node->getChild('description')->getValue();
     }
     $object += self::$defaults;
     if ($node->shouldDropOnUpdate()) {
         $context->log(sprintf("%s: deleting menu and children", $node->getPath()));
         menu_delete($object);
     }
     menu_save($object);
     return $node->getName();
 }
Example #6
0
 public function execute(Node $node, Context $context)
 {
     if ($node instanceof MacroReferenceNode) {
         $path = $node->getMacroPath();
         // Provided that users might want some things hardcoded, everything
         // under the 'macro' root node will be considered as macros
         if (false === strpos($path, Path::SEP)) {
             $path = 'macro' . Path::SEP . $path;
         }
         $macro = (new Path($path))->find($context->getGraph());
         if (!$macro) {
             throw new CompilerException(sprintf("'%s': '%s' macro does not exist", $node->getPath(), $node->getValue()));
         }
         if (1 !== count($macro)) {
             throw new CompilerException(sprintf("'%s': '%s' multiple targets found", $node->getPath(), $node->getValue()));
         }
         $node->getParent()->replaceChild($node->getName(), reset($macro)->duplicate($node->getName()));
     }
 }
 public function execute(Node $node, Context $context)
 {
     $sorted = array();
     $orphans = array();
     $path = $node->getPath();
     foreach ($node->getChildren() as $key => $child) {
         if ($child->hasChild('inherit')) {
             $parent = $child->getChild('inherit')->getValue();
             if (!is_string($parent)) {
                 $context->logCritical(sprintf("%s: %s: malformed inherit directive", $path, $key));
             }
             if (!$node->hasChild($parent)) {
                 $context->logCritical(sprintf("%s: %s: cannot inherit from non existing: %s", $path, $key, $parent));
             }
             if ($key === $parent) {
                 $context->logCritical(sprintf("%s: %s: cannot inherit from itself", $path, $key));
             }
             $child->removeChild('inherit');
             $orphans[$key] = $parent;
         } else {
             $sorted[$key] = array();
         }
     }
     while (!empty($orphans)) {
         $count = count($orphans);
         foreach ($orphans as $key => $parent) {
             if (isset($sorted[$parent])) {
                 $sorted[$parent][] = $key;
                 $sorted[$key] = array();
                 unset($orphans[$key]);
             }
         }
         if (count($orphans) === $count) {
             $context->logCritical(sprintf("%s: circular dependency detected", $path));
         }
     }
     foreach (array_filter($sorted) as $parent => $children) {
         foreach ($children as $name) {
             $node->getChild($name)->setAttribute('inherits', $node->getChild($parent)->getPath());
         }
     }
 }
 /**
  * Build graph from provided sources
  */
 public function build()
 {
     $context = new Context();
     $global = $context->time('compiler');
     $timer = $context->time('compiler:parse');
     $ast = (new ArrayTreeBuilder())->parse($this->buildRawArray($context));
     $timer->stop();
     // We have a "naked" AST with no business meaning whatsover, now we
     // need to process low level and meaningless transformations, such
     // as macro processing
     $context->setGraph($ast);
     // First, macro processing, this will deeply change the graph, so it
     // needs to happen first and alone, prior to anything else
     $timer = $context->time('compiler:macro');
     $visitor = new Visitor();
     $visitor->addProcessor(new MacroPass());
     $visitor->execute($ast, $context);
     $timer->stop();
     // Same goes for inheritance, it is business-free and low level
     $timer = $context->time('compiler:inheritance');
     $visitor = new Visitor();
     $visitor->addProcessor(new InheritancePass());
     $visitor->execute($ast, $context);
     $timer->stop();
     // Then, we need to have a business mean-something graph, so let's
     // apply path map conversion, so let's go!
     $timer = $context->time('compiler:conversion');
     $visitor = new Visitor();
     $visitor->addProcessor(new BusinessConversionPass());
     $visitor->execute($ast, $context);
     $timer->stop();
     // From this point, graph should not be modified anymore, which means
     // we can safely count nodes from this point
     $timer = $context->time('compiler:attributes');
     $visitor = new Visitor();
     $visitor->addProcessor(new CountPass());
     $visitor->addProcessor(new ExpressionProcessor());
     $visitor->addProcessor(new DrupalAttributesProcessor());
     $visitor->execute($ast, $context);
     $timer->stop();
     $global->stop();
     return $context;
 }
 public function synchronize(NodeInterface $node, Context $context, $dirtyAllowed = false)
 {
     /* @var $node ViewNode */
     $entityType = $node->getEntityType();
     $bundle = $node->getBundle();
     $name = $node->getName();
     // First populate the variable that will be used during the
     // hook_entity_info_alter() call to populate the view modes
     $viewModes = variable_get(USYNC_VAR_VIEW_MODE, []);
     $viewModes[$entityType][$name] = $name;
     variable_set(USYNC_VAR_VIEW_MODE, $viewModes);
     // First grab a list of everything that can be displayed in view
     // modes with both extra fields and real fields
     $instances = field_info_instances($entityType, $bundle);
     $bundleSettings = field_bundle_settings($entityType, $bundle);
     $extra = $this->getExtraFieldsDisplay($entityType, $bundle);
     $weight = 0;
     $displayExtra = [];
     $displayField = [];
     // Then deal with fields and such
     foreach ($node->getValue() as $propertyName => $formatter) {
         if (isset($instances[$propertyName])) {
             $display = array();
             // We are working with a field
             if (!is_array($formatter)) {
                 if (true === $formatter || 'default' === $formatter) {
                     $formatter = array();
                 } else {
                     if (false === $formatter || null === $formatter || 'delete' === $formatter) {
                         continue;
                     } else {
                         if (!is_string($formatter)) {
                             $context->logWarning(sprintf("%s: %s invalid value for formatter", $node->getPath(), $propertyName));
                             $formatter = array();
                         } else {
                             $display['type'] = $formatter;
                         }
                     }
                 }
             } else {
                 $display = $formatter;
             }
             // Merge default and save
             $displayField[$propertyName] = drupal_array_merge_deep($this->getFieldDefault($node, $entityType, $bundle, $propertyName, $context), $display, array('weight' => $weight++));
         } else {
             if (isset($extra[$propertyName])) {
                 // We are working with and extra field
                 if (!is_array($formatter)) {
                     if (true === $formatter || 'default' === $formatter) {
                         $formatter = array();
                     } else {
                         if (false === $formatter || null === $formatter || 'delete' === $formatter) {
                             continue;
                         } else {
                             $context->logWarning(sprintf("%s: %s extra fields can only be delete or default", $node->getPath(), $propertyName));
                         }
                     }
                 }
                 // Merge default and save
                 $displayExtra[$propertyName] = ['visible' => true, 'weight' => $weight++];
             } else {
                 $context->logError(sprintf("%s: %s property is nor a field nor an extra field", $node->getPath(), $propertyName));
             }
         }
     }
     // Iterate over the fields and update each instance: we don't
     // need to do it with the $displayExtra property since it is
     // already the correctly formatted variable
     foreach ($displayField as $fieldName => $display) {
         $instances[$fieldName]['display'][$name] = $display;
     }
     // Remove non configured fields and extra fields from display
     foreach ($instances as $fieldName => $instance) {
         if (!isset($displayField[$fieldName])) {
             $instance['display'][$name] = array('type' => 'hidden');
         }
         if ($dirtyAllowed) {
             $data = $instance;
             unset($data['id'], $data['field_id'], $data['field_name'], $data['entity_type'], $data['bundle'], $data['deleted']);
             db_update('field_config_instance')->condition('id', $instance['id'])->fields(['data' => serialize($data)])->execute();
         } else {
             field_update_instance($instance);
         }
     }
     foreach (array_keys($extra) as $propertyName) {
         if (isset($displayExtra[$propertyName])) {
             $bundleSettings['extra_fields']['display'][$propertyName][$name] = $displayExtra[$propertyName];
         } else {
             $bundleSettings['extra_fields']['display'][$propertyName][$name] = ['visible' => false, 'weight' => $weight++];
         }
     }
     $bundleSettings['view_modes'][$name] = ['label' => $name, 'custom_settings' => true];
     if ($dirtyAllowed) {
         // Hopefully nothing about display is really cached into the
         // internal field cache class, except the raw display array
         // into each instance, but nothing will use that except this
         // specific view mode implementation, we are going to delay
         // a few cache clear calls at the very end of the processing.
         // From field_bundle_settings().
         variable_set('field_bundle_settings_' . $entityType . '__' . $bundle, $bundleSettings);
     } else {
         field_bundle_settings($entityType, $bundle, $bundleSettings);
     }
     if ($dirtyAllowed) {
         // From field_update_instance()
         cache_clear_all('*', 'cache_field', true);
         // From field_info_cache_clear()
         drupal_static_reset('field_view_mode_settings');
         // We need to clear cache in order for later view modes to
         // load the right instance and prevent them for overriding
         // what we actually did here
         entity_info_cache_clear();
         _field_info_field_cache()->flush();
     }
 }
Example #10
0
 public function synchronize(NodeInterface $node, Context $context, $dirtyAllowed = false)
 {
     /* @var $node FieldNode */
     $object = $node->getValue();
     if (!is_array($object)) {
         $object = array();
     }
     if (!isset($object['type'])) {
         $context->logCritical(sprintf("%s: has no type", $node->getPath()));
     }
     $name = $node->getName();
     $type = $object['type'];
     $typeInfo = field_info_field_types($type);
     if (empty($typeInfo)) {
         $context->logCritical(sprintf("%s: type %s does not exist", $node->getPath(), $type));
     }
     if ($this->exists($node, $context)) {
         $existing = $this->getExistingObject($node, $context);
     } else {
         $existing = null;
     }
     if (array_key_exists('settings', $object) && !is_array($object['settings'])) {
         $context->log(sprintf("%s: no settings provided, defaulting with empty array", $node->getPath()));
         $object['settings'] = array();
     }
     $object['field_name'] = $name;
     if (empty($object['cardinality'])) {
         $object['cardinality'] = 1;
     }
     // Consistency check, prior to do anything, ensure the database tables
     // are not already there, this happens, sometimes
     if (!$existing) {
         if (empty($object['storage']) || 'field_sql_storage' === $object['storage']['type']) {
             // Prevents warning on unspecified key
             if (!isset($object['deleted'])) {
                 $object['deleted'] = false;
             }
             $tables = [_field_sql_storage_tablename($object), _field_sql_storage_revision_tablename($object)];
             foreach ($tables as $table) {
                 if (db_table_exists($table)) {
                     $context->logDataloss(sprintf("%s: %s: table already exists prior to creating field", $node->getPath(), $table));
                     // If code has not broken here, then go for deletion
                     db_drop_table($table);
                 }
             }
         }
     }
     if ($existing) {
         $doDelete = false;
         $eType = $existing['type'];
         // Ensure the cardinality change if any is safe to proceed with
         $cardinality = $object['cardinality'] - $existing['cardinality'];
         if (0 !== $cardinality) {
             if (0 < $cardinality || -1 == $object['cardinality']) {
                 $context->log(sprintf("%s: safe cardinality change", $node->getPath()));
             } else {
                 // @todo Ensure there is data we can save in field
                 if (false) {
                     $context->log(sprintf("%s: safe cardinality change due to data shape", $node->getPath()));
                 } else {
                     $context->logDataloss(sprintf("%s: unsafe cardinality change", $node->getPath()));
                 }
             }
         }
         if ($type !== $eType) {
             $doDelete = true;
             $instances = $this->getInstances($name);
             if (empty($instances)) {
                 $context->logWarning(sprintf("%s: type change (%s -> %s): no instances", $node->getPath(), $type, $eType));
             } else {
                 // @todo Ensure there is data if there is instances
                 if (false) {
                     $context->logWarning(sprintf("%s: type change (%s -> %s): existing instances are empty", $node->getPath(), $type, $eType));
                 } else {
                     // @todo Safe should ensure schema is the same
                     if (false) {
                         $context->logWarning(sprintf("%s: type change (%s -> %s): field schema is the same", $node->getPath(), $type, $eType));
                     } else {
                         $context->logDataloss(sprintf("%s: type change (%s -> %s): data loss detected", $node->getPath(), $type, $eType));
                     }
                 }
             }
         }
         if ($doDelete) {
             $this->deleteExistingObject($node, $context);
             field_create_field($object);
             // @todo Recreate instances
         } else {
             field_update_field($object);
         }
     } else {
         field_create_field($object);
     }
 }
Example #11
0
 public function execute(Node $node, Context $context)
 {
     $context->incr('node');
 }
Example #12
0
 /**
  * Extract meaningfull objects from the graph, and apply dependency sort
  *
  * @param Context $context
  * @param LoaderInterface[] $loaders
  */
 protected function extractObjects(Context $context, array $loaders)
 {
     $dependencyMap = [];
     $timer = $context->time('loader:extract');
     $visitor = new Visitor();
     $visitor->addProcessor(function (NodeInterface $node, Context $context) use($loaders, &$dependencyMap) {
         $path = $node->getPath();
         foreach ($loaders as $loader) {
             if ($loader->canProcess($node)) {
                 $dependencyMap[$path] = [];
                 foreach ($loader->getDependencies($node, $context) as $dependency) {
                     $dependencyMap[$path][] = $dependency;
                 }
             }
         }
     });
     $visitor->execute($context->getGraph(), $context);
     $timer->stop();
     return $this->resolveDependencies($dependencyMap, $context);
 }