public function testError() { $instance = new DescriptionProcessor(); $instance->addError('abc'); $this->assertEquals(array('abc'), $instance->getErrors()); $instance->addErrorWithMsgKey('Foo'); $this->assertCount(2, $instance->getErrors()); }
/** * Parse a property description (the part of an inline query that * is in between "[[Some property::" and the closing "]]" and create a * suitable description. The "::" is the first chunk on the current * string. */ private function getPropertyDescription($propertyName, &$setNS) { $this->readChunk(); // consume separator ":=" or "::" // first process property chain syntax (e.g. "property1.property2::value"), escaped by initial " ": $propertynames = $propertyName[0] == ' ' ? array($propertyName) : explode('.', $propertyName); $properties = array(); $typeid = '_wpg'; $inverse = false; foreach ($propertynames as $name) { if (!$this->isPagePropertyType($typeid)) { // non-final property in chain was no wikipage: not allowed $this->descriptionProcessor->addErrorWithMsgKey('smw_valuesubquery', $name); return null; ///TODO: read some more chunks and try to finish [[ ]] } $property = SMWPropertyValue::makeUserProperty($name); if (!$property->isValid()) { // illegal property identifier $this->descriptionProcessor->addError($property->getErrors()); return null; ///TODO: read some more chunks and try to finish [[ ]] } $typeid = $property->getDataItem()->findPropertyTypeID(); $inverse = $property->isInverse(); $properties[] = $property; } ///NOTE: after iteration, $property and $typeid correspond to last value $innerdesc = null; $continue = true; while ($continue) { $chunk = $this->readChunk(); switch ($chunk) { case '+': // wildcard, add namespaces for page-type properties if (!is_null($this->defaultNamespace) && ($this->isPagePropertyType($typeid) || $inverse)) { $innerdesc = $this->descriptionProcessor->constructDisjunctiveCompoundDescriptionFrom($innerdesc, $this->defaultNamespace); } else { $innerdesc = $this->descriptionProcessor->constructDisjunctiveCompoundDescriptionFrom($innerdesc, new ThingDescription()); } $chunk = $this->readChunk(); break; case '<q>': // subquery, set default namespaces if ($this->isPagePropertyType($typeid) || $inverse) { $this->pushDelimiter('</q>'); $setsubNS = true; $innerdesc = $this->descriptionProcessor->constructDisjunctiveCompoundDescriptionFrom($innerdesc, $this->getSubqueryDescription($setsubNS)); } else { // no subqueries allowed for non-pages $this->descriptionProcessor->addErrorWithMsgKey('smw_valuesubquery', end($propertynames)); $innerdesc = $this->descriptionProcessor->constructDisjunctiveCompoundDescriptionFrom($innerdesc, new ThingDescription()); } $chunk = $this->readChunk(); break; default: // normal object value // read value(s), possibly with inner [[...]] $open = 1; $value = $chunk; $continue2 = true; // read value with inner [[, ]], || while ($open > 0 && $continue2) { $chunk = $this->readChunk('\\[\\[|\\]\\]|\\|\\||\\|'); switch ($chunk) { case '[[': // open new [[ ]] $open++; break; case ']]': // close [[ ]] $open--; break; case '|': case '||': // terminates only outermost [[ ]] if ($open == 1) { $open = 0; } break; case '': ///TODO: report error; this is not good right now $continue2 = false; break; } if ($open != 0) { $value .= $chunk; } } ///NOTE: at this point, we normally already read one more chunk behind the value $innerdesc = $this->descriptionProcessor->constructDisjunctiveCompoundDescriptionFrom($innerdesc, $this->descriptionProcessor->constructDescriptionForPropertyObjectValue($property->getDataItem(), $value)); } $continue = $chunk == '||'; } if (is_null($innerdesc)) { // make a wildcard search $innerdesc = !is_null($this->defaultNamespace) && $this->isPagePropertyType($typeid) ? $this->descriptionProcessor->constructDisjunctiveCompoundDescriptionFrom($innerdesc, $this->defaultNamespace) : $this->descriptionProcessor->constructDisjunctiveCompoundDescriptionFrom($innerdesc, new ThingDescription()); $this->descriptionProcessor->addErrorWithMsgKey('smw_propvalueproblem', $property->getWikiValue()); } $properties = array_reverse($properties); foreach ($properties as $property) { $innerdesc = new SomeProperty($property->getDataItem(), $innerdesc); } $result = $innerdesc; return $this->finishLinkDescription($chunk, false, $result, $setNS); }