<?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
 */

/**
 * BLOB datatype
 *
 * This datatype is not editable in backend and can contain any data you like,
 * even binary. By default, data is encoded as JSON, but you can change this to
 * either 'php' to use serialize/unserialize or your own serializer, which can
 * do whatever you like.
 */
class _WV_Datatype_Blob extends _WV_Datatype_Base implements WV_IDatatype {
	public function renderForm(sly_Form $form, WV_IProperty $property, $value) {
		if ($property->isMultilingual()) {
			throw new WV_Exception_Datatype('BLOB datatype cannot be multilingual (not yet implemented).');
		}

		// In an ideal world, we would not have to include the data in the form
		// and make it only available via API. But nearly all addOns using the
		// datatypes except serializeForm() to return the data to save it. This
		// is also why the 'text' datatype embeds the text as a hidden input field.

		$value = reset($value);
		$value = base64_encode($value);

		$form->addHiddenValue('property_'.$property->getID().'_value', $value);

		return $form;
	}

	public function serializeForm(WV_IProperty $property) {
		$value = sly_post('property_'.$property->getID().'_value', 'string', '');

		if ($value !== '') {
			$value = base64_decode($value);
		}

		return $value;
	}

	public function serializeValue($value, array $params) {
		return $this->serializer($value, $params, 'encode');
	}

	public function deserializeValue($value, array $params) {
		return $this->serializer($value, $params, 'decode');
	}

	protected function getDefaultParams() {
		return array('serializer' => 'json');
	}

	protected function serializer($value, array $params, $mode) {
		$params     = $this->deserializeParams($params);
		$serializer = $params['serializer'];

		switch ($serializer) {
			case 'json':
				return $mode === 'decode' ? json_decode($value, true) : json_encode($value);

			case 'php':
				return $mode === 'decode' ? unserialize($value) : serialize($value);

			default:
				if (!is_callable($serializer)) {
					throw new LogicException('Invalid "serializer" setting: '.$serializer.' could not be found.');
				}

				return call_user_func_array($serializer, array($value, $params, $mode));
		}
	}
}
