/**
     * {@inheritdoc}
     */
    protected function doSave($id, EntityInterface $entity)
    {
        $bundle = $entity->bundle();
        // Generate an ID before saving, if none is available. If the ID generation
        // occurs earlier in the process (like on EntityInterface::create()), the
        // entity might be considered not new by modules that don't strictly use the
        // EntityInterface::isNew() method.
        if (empty($id)) {
            $id = $this->generateId();
            $entity->{$this->idKey} = (string) $id;
        }
        // If the target graph is set, it has priority over the one the entity is
        // loaded from. If no target graph is set, use the previous one.
        $target_graph = $this->getGraphHandler()->getTargetGraphFromEntity($entity);
        $graph_uri = $this->getBundleGraphUri($bundle, $target_graph);
        $insert = '';
        $properties = $this->mappingHandler->getEntityTypeMappedProperties($entity);
        $subj = '<' . (string) $id . '>';
        $properties_list = "<" . implode(">, <", $properties['flat']) . ">";
        foreach ($entity->toArray() as $field_name => $field) {
            foreach ($field as $field_item) {
                foreach ($field_item as $column => $value) {
                    if (!isset($properties['by_field'][$field_name][$column])) {
                        continue;
                    }
                    $pred = '<' . (string) $properties['by_field'][$field_name][$column] . '>';
                    if (!filter_var($value, FILTER_VALIDATE_URL) === FALSE) {
                        $obj = '<' . $value . '>';
                    } else {
                        // @todo This is most probably prone to Sparql injection..!
                        $obj = '"""' . $value . '"""';
                    }
                    $insert .= $subj . ' ' . $pred . ' ' . $obj . '  .' . "\n";
                }
            }
        }
        // Save the bundle.
        $rdf_bundle_mapping = $this->mappingHandler->getRdfBundleMappedUri($entity->getEntityType()->getBundleEntityType(), $entity->bundle());
        $rdf_bundle = $rdf_bundle_mapping[$entity->bundle()];
        $insert .= $subj . ' ' . $this->rdfBundlePredicate . ' <' . $rdf_bundle . '>  .' . "\n";
        $query = <<<QUERY
DELETE {
  GRAPH <{$graph_uri}> {
    <{$id}> ?field ?value
  }
}
WHERE {
  GRAPH <{$graph_uri}> {
    <{$id}> ?field ?value .
    FILTER (?field IN ({$properties_list}))
  }
}
QUERY;
        if (!$entity->isNew()) {
            $this->sparql->query($query);
        }
        // @todo Do in one transaction... If possible.
        $query = "INSERT DATA INTO <{$graph_uri}> {\n" . $insert . "\n" . '}';
        $this->sparql->query($query);
    }
Example #2
0
 /**
  * {@inheritdoc}
  */
 public function condition($property, $value = NULL, $operator = '=', $langcode = NULL)
 {
     $key = $property . '-' . $operator;
     $field_storage_definitions = \Drupal::service('entity.manager')->getFieldStorageDefinitions($this->entityTypeId);
     /*
      * Ok, so what is all this:
      * We need to convert our conditions into some sparql compatible conditions.
      */
     $bundle = $this->entityType->getKey('bundle');
     $id = $this->entityType->getKey('id');
     $label = $this->entityType->getKey('label');
     switch ($key) {
         // @todo Limit the graphs here to the set bundles.
         case $bundle . '-IN':
             $rdf_bundles = $this->mappingHandler->getBundleUriList($this->entityType->getBundleEntityType(), $value);
             if ($rdf_bundles) {
                 $this->condition->condition('?entity', '?bundlepredicate', '?type');
                 $this->filterAdded = TRUE;
                 $predicates = "(<" . implode(">, <", $this->entityStorage->bundlePredicate()) . ">)";
                 $this->filter->filter('?bundlepredicate IN ' . $predicates);
                 $this->filter->filter('?type IN ' . $rdf_bundles);
             }
             return $this;
         case $bundle . '-=':
             $mapping = $this->mappingHandler->getRdfBundleMappedUri($this->entityType->getBundleEntityType(), $value);
             $bundle = $mapping[$value];
             if ($bundle) {
                 $this->condition->condition('?entity', '?bundlepredicate', SparqlArg::uri($bundle));
                 $predicates = "(<" . implode(">, <", $this->entityStorage->bundlePredicate()) . ">)";
                 $this->filter->filter('?bundlepredicate IN ' . $predicates);
                 $this->filterAdded = TRUE;
             }
             return $this;
         case $id . '-IN':
             if ($value) {
                 $ids_list = "(<" . implode(">, <", $value) . ">)";
                 if (!$this->filterAdded) {
                     $this->condition->condition('?entity', '?bundlepredicate', '?type');
                     $predicates = "(<" . implode(">, <", $this->entityStorage->bundlePredicate()) . ">)";
                     $this->filter->filter('?bundlepredicate IN ' . $predicates);
                     $this->filterAdded = TRUE;
                 }
                 $this->filter->filter('?entity IN ' . $ids_list);
             }
             return $this;
         case $id . '-NOT IN':
         case $id . '-<>':
             if ($value) {
                 if (is_array($value)) {
                     $ids_list = "(<" . implode(">, <", $value) . ">)";
                 } else {
                     $ids_list = "(<" . $value . ">)";
                 }
                 if (!$this->filterAdded) {
                     $this->condition->condition('?entity', '?bundlepredicate', '?type');
                     $predicates = "(<" . implode(">, <", $this->entityStorage->bundlePredicate()) . ">)";
                     $this->filter->filter('?bundlepredicate IN ' . $predicates);
                     $this->filterAdded = TRUE;
                 }
                 $this->filter->filter('!(?entity IN ' . $ids_list . ')');
             }
             return $this;
         case $id . '-=':
             if (!$value) {
                 return $this;
             }
             $id = '<' . $value . '>';
             if (!$this->filterAdded) {
                 $this->condition->condition('?entity', '?bundlepredicate', '?type');
                 $predicates = "(<" . implode(">, <", $this->entityStorage->bundlePredicate()) . ">)";
                 $this->filter->filter('?bundlepredicate IN ' . $predicates);
                 $this->filterAdded = TRUE;
             }
             $this->filter->filter('?entity IN ' . SparqlArg::literal($id));
             break;
         case $label . '-=':
             preg_match('/\\((.*?)\\)/', $value, $matches);
             $matching = array_pop($matches);
             if ($matching) {
                 $ids = "(<{$matching}>)";
                 $this->filter->filter('?entity IN ' . $ids);
             } else {
                 if (file_valid_uri($value)) {
                     $ids = "(<{$value}>)";
                     $this->filter->filter('?entity IN ' . $ids);
                 } else {
                     $mapping = $this->mappingHandler->getEntityTypeLabelPredicates($this->entityTypeId);
                     $label_list = "(<" . implode(">, <", array_unique(array_keys($mapping))) . ">)";
                     $this->condition->condition('?entity', '?label_type', '?label');
                     $this->filter->filter('?label_type IN ' . $label_list);
                     $this->filter->filter('str(?label) = "' . $value . '"');
                 }
             }
             return $this;
         case $label . '-CONTAINS':
             $mapping = $this->mappingHandler->getEntityTypeLabelPredicates($this->entityTypeId);
             $label_list = "(<" . implode(">, <", array_unique(array_keys($mapping))) . ">)";
             $this->condition->condition('?entity', '?label_type', '?label');
             $this->filter->filter('?label_type IN ' . $label_list);
             if ($value) {
                 $this->filter->filter('regex(?label, "' . $value . '", "i")');
                 $this->filter->filter('(lang(?label) = "" || langMatches(lang(?label), "EN"))');
             }
             return $this;
         case '_field_exists-EXISTS':
         case '_field_exists-NOT EXISTS':
             $field_rdf_name = $this->getFieldRdfPropertyName($value, $field_storage_definitions);
             if (!UrlHelper::isValid($field_rdf_name, TRUE) === FALSE) {
                 $field_rdf_name = SparqlArg::uri($field_rdf_name);
             }
             if ($field_rdf_name) {
                 $this->filter('?entity ' . $field_rdf_name . ' ?c', 'FILTER ' . $operator);
             }
             return $this;
     }
     if ($operator == '=') {
         if (!$value) {
             return $this;
         }
         // @todo this code will be handled in ISAICP-2631
         if (strpos($property, '.') !== FALSE) {
             list($field_name, $column) = explode('.', $property);
         } else {
             $field_name = $property;
         }
         $field_rdf_name = $this->getFieldRdfPropertyName($field_name, $field_storage_definitions);
         if (!UrlHelper::isValid($value, TRUE) === FALSE) {
             $value = SparqlArg::uri($value);
         } else {
             $value = SparqlArg::literal($value);
         }
         $this->condition->condition('?entity', SparqlArg::uri($field_rdf_name), $value);
     }
     return $this;
 }