summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/Deserializers/DVDescriptionDeserializer/DescriptionDeserializer.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/src/Deserializers/DVDescriptionDeserializer/DescriptionDeserializer.php')
-rw-r--r--www/wiki/extensions/SemanticMediaWiki/src/Deserializers/DVDescriptionDeserializer/DescriptionDeserializer.php180
1 files changed, 180 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/src/Deserializers/DVDescriptionDeserializer/DescriptionDeserializer.php b/www/wiki/extensions/SemanticMediaWiki/src/Deserializers/DVDescriptionDeserializer/DescriptionDeserializer.php
new file mode 100644
index 00000000..4230784c
--- /dev/null
+++ b/www/wiki/extensions/SemanticMediaWiki/src/Deserializers/DVDescriptionDeserializer/DescriptionDeserializer.php
@@ -0,0 +1,180 @@
+<?php
+
+namespace SMW\Deserializers\DVDescriptionDeserializer;
+
+use Deserializers\DispatchableDeserializer;
+use SMW\ApplicationFactory;
+use SMW\DataItemFactory;
+use SMW\Query\DescriptionFactory;
+use SMW\Query\QueryComparator;
+use SMWDataValue as DataValue;
+
+/**
+ * @private
+ *
+ * Create an Description object based on a value string that was entered
+ * in a query. Turning inputs that a user enters in place of a value within
+ * a query string into query conditions is often a standard procedure. The
+ * processing must take comparators like "<" into account, but otherwise
+ * the normal parsing function can be used. However, there can be datatypes
+ * where processing is more complicated, e.g. if the input string contains
+ * more than one value, each of which may have comparators, as in
+ * SMWRecordValue. In this case, it makes sense to overwrite this method.
+ * Another reason to do this is to add new forms of comparators or new ways
+ * of entering query conditions.
+ *
+ * The resulting Description may or may not make use of the datavalue
+ * object that this function was called on, so it must be ensured that this
+ * value is not used elsewhere when calling this method. The function can
+ * return ThingDescription to not impose any condition, e.g. if parsing
+ * failed. Error messages of this DataValue object are propagated.
+ *
+ * @license GNU GPL v2+
+ * @since 2.3
+ *
+ * @author mwjames
+ */
+abstract class DescriptionDeserializer implements DispatchableDeserializer {
+
+ /**
+ * @var DescriptionFactory
+ */
+ protected $descriptionFactory;
+
+ /**
+ * @var DataItemFactory
+ */
+ protected $dataItemFactory;
+
+ /**
+ * @var array
+ */
+ protected $errors = [];
+
+ /**
+ * @var DataValue
+ */
+ protected $dataValue;
+
+ /**
+ * @since 2.5
+ *
+ * @param DescriptionFactory|null $descriptionFactory
+ * @param DataItemFactory|null $dataItemFactory
+ */
+ public function __construct( DescriptionFactory $descriptionFactory = null, DescriptionFactory $dataItemFactory = null ) {
+ $this->descriptionFactory = $descriptionFactory;
+ $this->dataItemFactory = $dataItemFactory;
+
+ if ( $this->descriptionFactory === null ) {
+ $this->descriptionFactory = ApplicationFactory::getInstance()->getQueryFactory()->newDescriptionFactory();
+ }
+
+ if ( $this->dataItemFactory === null ) {
+ $this->dataItemFactory = ApplicationFactory::getInstance()->getDataItemFactory();
+ }
+ }
+
+ /**
+ * @since 2.3
+ *
+ * @param DataValue $dataValue
+ */
+ public function setDataValue( DataValue $dataValue ) {
+ $this->dataValue = $dataValue;
+ $this->errors = [];
+ }
+
+ /**
+ * @since 2.3
+ *
+ * @param string $error
+ */
+ public function addError( $error ) {
+
+ if ( is_array( $error ) ) {
+ return $this->errors = array_merge( $this->errors, $error );
+ }
+
+ $this->errors[] = $error;
+ }
+
+ /**
+ * @since 2.3
+ *
+ * @return array
+ */
+ public function getErrors() {
+ return $this->errors;
+ }
+
+ /**
+ * Helper function for DescriptionDeserializer::deserialize that prepares a
+ * single value string, possibly extracting comparators. $value is changed
+ * to consist only of the remaining effective value string (without the
+ * comparator).
+ *
+ * @param string $value
+ * @param string|integer $comparator
+ */
+ protected function prepareValue( &$value, &$comparator ) {
+ $comparator = QueryComparator::getInstance()->extractComparatorFromString( $value );
+
+ // [[in:lorem ipsum]] / [[Has text::in:lorem ipsum]] to be turned into a
+ // proximity match where lorem AND ipsum needs to be present in the
+ // indexed match field.
+ //
+ // For those query engines that support those search patterns!
+ if ( $comparator === SMW_CMP_IN ) {
+ $comparator = SMW_CMP_LIKE;
+
+ // Looking for something like [[in:phrase:foo]]
+ if ( strpos( $value, 'phrase:' ) !== false ) {
+ $value = str_replace( 'phrase:', '', $value );
+ $value = '"' . $value . '"';
+ }
+
+ // `in:...` is for the "busy" user to avoid adding wildcards now and
+ // then to the value string
+ $value = "*$value*";
+
+ // No property and the assumption is [[in:...]] with the expected use
+ // of the wide proximity as indicated by an additional `~`
+ if ( $this->dataValue->getProperty() === null ) {
+ $value = "~$value";
+ }
+ }
+
+ // [[not:foo bar]]
+ // For those query engines that support those text search patterns!
+ if ( $comparator === SMW_CMP_NOT ) {
+ $comparator = SMW_CMP_NLKE;
+
+ $value = str_replace( '!', '', $value );
+
+ // Opposed to `in:` which includes *, `not:` is intended to match
+ // only the exact entered term. It can be extended using *
+ // if necessary (e.g. [[Has text::not:foo*]]).
+
+ // Use as phrase to signal an exact term match for a wide proximity
+ // search
+ if ( $this->dataValue->getProperty() === null ) {
+ $value = "~\"$value\"";
+ }
+ }
+
+ // [[phrase:lorem ipsum]] to be turned into a promixity phrase_match
+ // where the entire string (incl. its order) are to be matched.
+ //
+ // For those query engines that support those search patterns!
+ if ( $comparator === SMW_CMP_PHRASE ) {
+ $comparator = SMW_CMP_LIKE;
+ $value = '"' . $value . '"';
+
+ if ( $this->dataValue->getProperty() === null ) {
+ $value = "~$value";
+ }
+ }
+ }
+
+}