/** * add a filter from the filter box - these filters match some predefined schemes * (like "equals", "contains") * * @param string $property * @param boolean $isInverse whether the property is a indirect property of the resources * @param string $propertyLabel label affects the created variable * @param string $filter the type of filter ("equals", "bound", "larger", "smaller", "between", "contains") * @param string $value * @param string $valueSecondary * @param string $valuetype ("uri" or "literal" or "typed-literal") * @param string $literaltype (if valuetype is set to "typed-literal", you can pass a URI here) * @param boolean $hidden whether to hide this filter in the filter box GUI * @param string $id optional predined ID, will be generated normally * @param boolean $negate whether to invert the condition * @param boolean $optional * * @return string id * @throws RuntimeException */ public function addFilter($property, $isInverse, $propertyLabel, $filter, $value = null, $valueSecondary = null, $valuetype = 'literal', $literaltype = null, $hidden = false, $id = null, $negate = false, $optional = false) { if ($id == null) { $id = 'box' . count($this->_filter); } else { if (isset($this->_filter[$id])) { $this->removeFilter($id); } } $prop = new Erfurt_Sparql_Query2_IriRef($property); if (!empty($value)) { switch ($valuetype) { case 'uri': $valueObj = new Erfurt_Sparql_Query2_IriRef($value); if (!empty($valueSecondary)) { $valueSecondaryObj = new Erfurt_Sparql_Query2_IriRef($valueSecondary); } break; case 'literal': if (!empty($literaltype)) { //with language tags $valueObj = new Erfurt_Sparql_Query2_RDFLiteral($value, $literaltype); if (!empty($valueSecondary)) { $valueSecondaryObj = new Erfurt_Sparql_Query2_RDFLiteral($valueSecondary, $literaltype); } } else { //no language tags if (is_array($value)) { $value = current($value); } $meta = ''; if (is_scalar($value) && !is_string($value) && !is_array($value)) { $meta = gettype($value); } $valueObj = new Erfurt_Sparql_Query2_RDFLiteral($value, $meta); if (!empty($valueSecondary)) { $valueSecondaryObj = new Erfurt_Sparql_Query2_RDFLiteral($valueSecondary, $meta); } } break; case 'typed-literal': if (in_array($literaltype, Erfurt_Sparql_Query2_RDFLiteral::$knownShortcuts)) { //is something like "bool" or "int" - will be converted from "1"^^xsd:int to 1 $valueObj = new Erfurt_Sparql_Query2_RDFLiteral($value, $literaltype); if (!empty($valueSecondary)) { $valueSecondaryObj = new Erfurt_Sparql_Query2_RDFLiteral($valueSecondary, $literaltype); } } else { // is a uri $valueObj = new Erfurt_Sparql_Query2_RDFLiteral($value, new Erfurt_Sparql_Query2_IriRef($literaltype)); if (!empty($valueSecondary)) { $valueSecondaryObj = new Erfurt_Sparql_Query2_RDFLiteral($valueSecondary, new Erfurt_Sparql_Query2_IriRef($literaltype)); } } break; default: throw new RuntimeException('called Ontowiki_Model_Instances::addFilter with ' . 'unknown param-value: valuetype = "' . $valuetype . '"'); } } switch ($filter) { case 'contains': $var = new Erfurt_Sparql_Query2_Var($propertyLabel); if (!$isInverse) { $triple = $this->_resourceQuery->addTriple($this->_resourceVar, $prop, $var); } else { $triple = $this->_resourceQuery->addTriple($var, $prop, $this->_resourceVar); } $valueObj->setValue(str_replace("\\", "\\\\", preg_quote($valueObj->getValue()))); $addFilter = null; if (!$negate) { $addFilter = new Erfurt_Sparql_Query2_Regex(new Erfurt_Sparql_Query2_Str($var), $valueObj); } else { $addFilter = new Erfurt_Sparql_Query2_UnaryExpressionNot(new Erfurt_Sparql_Query2_Regex(new Erfurt_Sparql_Query2_Str($var), $valueObj)); } $filterObj = $this->_resourceQuery->addFilter($addFilter); break; case 'equals': if ($valuetype == 'literal') { $valueVar = new Erfurt_Sparql_Query2_Var($propertyLabel); if (!$isInverse) { $triple = new Erfurt_Sparql_Query2_Triple($this->_resourceVar, $prop, $valueVar); } else { throw new RuntimeException('literal as value for an inverse property ' . 'is a literal subject which is not allowed'); } if ($negate) { $optionalGP = new Erfurt_Sparql_Query2_OptionalGraphPattern(); $optionalGP->addElement($triple); if ($optional) { $orExpression = new Erfurt_Sparql_Query2_ConditionalOrExpression(); $orExpression->addElement(new Erfurt_Sparql_Query2_UnaryExpressionNot(new Erfurt_Sparql_Query2_bound($valueVar))); $orExpression->addElement(new Erfurt_Sparql_Query2_NotEquals($valueVar, $valueObj)); $filterObj = $optionalGP->addFilter($orExpression); } else { $filterObj = $optionalGP->addFilter(new Erfurt_Sparql_Query2_NotEquals($valueVar, $valueObj)); } $this->_resourceQuery->addElement($optionalGP); $triple = $optionalGP; } else { $this->_resourceQuery->addElement($triple); $filterObj = $this->_resourceQuery->addFilter(new Erfurt_Sparql_Query2_Regex(new Erfurt_Sparql_Query2_Str($valueVar), new Erfurt_Sparql_Query2_RDFLiteral('^' . str_replace("\\", "\\\\", preg_quote($value)) . '$'))); } } else { if (!$isInverse) { $triple = $this->_resourceQuery->addTriple($this->_resourceVar, $prop, $valueObj); } else { $triple = $this->_resourceQuery->addTriple($valueObj, $prop, $this->_resourceVar); } } break; case 'larger': $var = new Erfurt_Sparql_Query2_Var($propertyLabel); if (!$isInverse) { $triple = $this->_resourceQuery->addTriple($this->_resourceVar, $prop, $var); } else { $triple = $this->_resourceQuery->addTriple($var, $prop, $this->_resourceVar); } $filterObj = $this->_resourceQuery->addFilter(new Erfurt_Sparql_Query2_Larger($var, $valueObj)); break; case 'smaller': $var = new Erfurt_Sparql_Query2_Var($propertyLabel); if (!$isInverse) { $triple = $this->_resourceQuery->addTriple($this->_resourceVar, $prop, $var); } else { $triple = $this->_resourceQuery->addTriple($var, $prop, $this->_resourceVar); } $filterObj = $this->_resourceQuery->addFilter(new Erfurt_Sparql_Query2_Smaller($var, $valueObj)); break; case 'between': $var = new Erfurt_Sparql_Query2_Var($propertyLabel); if (!$isInverse) { $triple = $this->_resourceQuery->addTriple($this->_resourceVar, $prop, $var); } else { $triple = $this->_resourceQuery->addTriple($var, $prop, $this->_resourceVar); } $filterObj = $this->_resourceQuery->addFilter(new Erfurt_Sparql_Query2_ConditionalAndExpression(array(new Erfurt_Sparql_Query2_Larger($var, $valueObj), new Erfurt_Sparql_Query2_Smaller($var, $valueSecondaryObj)))); break; case 'bound': $var = new Erfurt_Sparql_Query2_Var($propertyLabel); if (!$isInverse) { $triple = new Erfurt_Sparql_Query2_Triple($this->_resourceVar, $prop, $var); } else { $triple = new Erfurt_Sparql_Query2_Triple($var, $prop, $this->_resourceVar); } if ($negate) { $optionalGP = new Erfurt_Sparql_Query2_OptionalGraphPattern(); $optionalGP->addElement($triple); $this->_resourceQuery->addElement($optionalGP); $triple = $optionalGP; // to save this obj (see underneath 20 lines) } else { $this->_resourceQuery->addElement($triple); } if ($negate) { $filterObj = $this->_resourceQuery->addFilter(new Erfurt_Sparql_Query2_UnaryExpressionNot(new Erfurt_Sparql_Query2_bound($var))); } break; default: throw new RuntimeException('called Ontowiki_Model_Instances::addFilter with ' . 'unknown param-value: filtertype=' . $filter); } //these filters bring their own triple $this->removeAllTriple(); //save $this->_filter[$id] = array('id' => $id, 'mode' => 'box', 'property' => $property, 'isInverse' => $isInverse, 'propertyLabel' => $propertyLabel, 'filter' => $filter, 'value1' => $value, 'value2' => $valueSecondary, 'valuetype' => $valuetype, 'literaltype' => $literaltype, 'hidden' => $hidden, 'negate' => $negate, 'objects' => array($triple, isset($filterObj) ? $filterObj : null)); $this->invalidate(); return $id; }