<?php
/*
 * Copyright (c) 2013, webvariants GbR, http://www.webvariants.de
 *
 * This file is released under the terms of the MIT license. You can find the
 * complete text in the attached LICENSE file or online at:
 *
 * http://www.opensource.org/licenses/mit-license.php
 */

/**
 * Basisklasse für einfache stringbasierte Datentypen
 *
 * Dieser Datentyp kann bis zu 65k Zeichen lange einzeilige Strings als Werte
 * annehmen. Die Minimal- und Maximallänge kann dabei beschränkt werden.
 */
abstract class _WV_Datatype_Base_String extends _WV_Datatype_Base {
	/**
	 * Parameter auf Kompatibilität prüfen
	 *
	 * Diese Methode entscheidet, ob die gemachten Änderungen am Datentyp (an
	 * den Parametern) dazu führen, dass Daten konvertiert oder gelöscht werden
	 * müssen.
	 *
	 * Eine Nachbearbeitung ist notwendig, wenn die Maximallänge reduziert
	 * wurde.
	 *
	 * @param  array $oldParameters  die alten Parameter
	 * @param  array $newParameters  die neuen Parameter
	 * @return mixed                 true, wenn die Daten kompatibel sind, sonst ein array(Fehlermeldung, betroffene Objekte)
	 */
	public function checkParamCompatibility(array $oldParameters, array $newParameters) {
		extract($this->deserializeParams($oldParameters, 'old'));
		extract($this->deserializeParams($newParameters, 'new'));

		if ($newMaxlength < $oldMaxlength) {
			return array(t('devutils_datatype_stringbase_shrinked'), 'LENGTH(value) > '.$newMaxlength);
		}

		return true;
	}

	/**
	 * Inkompatible Datensätze verarbeiten
	 *
	 * Diese Methode löscht oder korrigiert durch das Bearbeiten des Datentyps
	 * inkompatibel gewordene Datensätze. Dabei werden die Werte der Objekte
	 * auf die neue Maximallänge gekürzt.
	 *
	 * @param array $oldParameters  die alten Parameter
	 * @param array $newParameters  die neuen Parameter
	 */
	public function getIncompatibilityUpdateStatement(array $oldParameters, array $newParameters) {
		extract($this->deserializeParams($oldParameters, 'old'));
		extract($this->deserializeParams($newParameters, 'new'));

		if ($newMaxlength < $oldMaxlength) {
			return array(
				array(
					'UPDATE',
					'$$$value_column$$$ = SUBSTRING($$$value_column$$$, 1, '.$newMaxlength.')',
					'LENGTH($$$value_column$$$) > '.$newMaxlength
				)
			);
		}

		return array();
	}

	public function isValueContained($valueToSearch, $valueFromDatabase, array $params, $filterParams) {
		if ($filterParams & WV_Datatype::FILTER_NOCASE) {
			$valueFromDatabase = mb_strtolower($valueFromDatabase);
			$valueToSearch     = mb_strtolower($valueToSearch);
		}

		// mb_strpos() throws warnings when $valueFromDatabase is empty
		if (mb_strlen($valueFromDatabase) === 0 || mb_strlen($valueToSearch) === 0) {
			return $valueToSearch === $valueFromDatabase;
		}

		if ($filterParams & WV_Datatype::FILTER_EXACTMATCH) return $valueToSearch == $valueFromDatabase;
		else return mb_strpos($valueFromDatabase, $valueToSearch) !== false;
	}

	public function serializeFormFilter($list, WV_IProperty $property) {
		$params = $property->getParams();
		extract($this->deserializeParams($params));

		foreach ($list as $value) {
			if (strlen($value) < $minlength) throw new WV_Exception_Datatype(t('devutils_datatype_stringbase_too_short', $minlength));
			if (strlen($value) > $maxlength) throw new WV_Exception_Datatype(t('devutils_datatype_stringbase_too_long', $maxlength));
		}

		return $list;
	}

	protected function getDefaultParams() {
		return array(
			'minlength'    => 0,
			'maxlength'    => 65535,
			'css'          => '',
			'width'        => '',
			'align'        => 'left',
			'annotation'   => '',
			'autocomplete' => ''
		);
	}
}
