Maslosoft Mangan API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
<?php
/**
* This software package is licensed under AGPL or Commercial license.
*
* @package maslosoft/mangan
* @licence AGPL or Commercial
* @copyright Copyright (c) Piotr Masełkowski <pmaselkowski@gmail.com>
* @copyright Copyright (c) Maslosoft
* @copyright Copyright (c) Others as mentioned in code
* @link https://maslosoft.com/mangan/
*/
namespace Maslosoft\Mangan\Transformers;
use Maslosoft\Addendum\Interfaces\AnnotatedInterface;
use Maslosoft\Mangan\Exceptions\TransformatorException;
use Maslosoft\Mangan\Helpers\Decorator\Decorator;
use Maslosoft\Mangan\Helpers\Decorator\ModelDecorator;
use Maslosoft\Mangan\Helpers\Finalizer\FinalizingManager;
use Maslosoft\Mangan\Helpers\PkManager;
use Maslosoft\Mangan\Helpers\PropertyFilter\Filter;
use Maslosoft\Mangan\Helpers\Sanitizer\Sanitizer;
use Maslosoft\Mangan\Meta\DocumentPropertyMeta;
use Maslosoft\Mangan\Meta\ManganMeta;
/**
* Transformer
*
* @author Piotr Maselkowski <pmaselkowski at gmail.com>
*/
abstract class Transformer
{
/**
* Returns the given object as an associative array
* @param AnnotatedInterface|object $model
* @param string[] $fields Fields to transform
* @return array an associative array of the contents of this object
*/
public static function fromModel(AnnotatedInterface $model, $fields = [])
{
$meta = static::getMeta($model);
$calledClass = get_called_class();
$decorator = new Decorator($model, $calledClass, $meta);
$md = new ModelDecorator($model, $calledClass, $meta);
$sanitizer = new Sanitizer($model, $calledClass, $meta);
$filter = new Filter($model, $calledClass, $meta);
$arr = [];
foreach ($meta->fields() as $name => $fieldMeta)
{
if (!empty($fields) && !in_array($name, $fields))
{
continue;
}
if (!$filter->fromModel($model, $fieldMeta))
{
continue;
}
$model->$name = $sanitizer->write($name, $model->$name);
$decorator->write($name, $arr);
$model->$name = $sanitizer->read($name, $model->$name);
}
$md->write($arr);
return FinalizingManager::fromModel($arr, static::class, $model);
}
/**
* Create document from array
*
* @param mixed[] $data
* @param string|object $className
* @param AnnotatedInterface $instance
* @return AnnotatedInterface
* @throws TransformatorException
*/
public static function toModel($data, $className = null, AnnotatedInterface $instance = null)
{
$data = (array) $data;
if (is_object($className))
{
$className = get_class($className);
}
if (!$className)
{
if (array_key_exists('_class', $data))
{
$className = $data['_class'];
}
else
{
if (null !== $instance)
{
$className = get_class($instance);
}
else
{
throw new TransformatorException('Could not determine document type');
}
}
}
if ($instance)
{
$model = $instance;
}
else
{
$model = new $className;
}
$meta = static::getMeta($model);
$calledClass = get_called_class();
$decorator = new Decorator($model, $calledClass, $meta);
$md = new ModelDecorator($model, $calledClass, $meta);
$sanitizer = new Sanitizer($model, $calledClass, $meta);
$filter = new Filter($model, $calledClass, $meta);
// Ensure that primary keys are processed first,
// as in some cases those could be processed *after* related
// document(s), which results in wrong _id (or pk) being passed.
$fieldsMeta = (array) $meta->fields();
$pks = (array)PkManager::getPkKeys($model);
foreach($pks as $key)
{
if(!array_key_exists($key, $fieldsMeta))
{
continue;
}
$pkMeta = $fieldsMeta[$key];
unset($fieldsMeta[$key]);
$fieldsMeta = array_merge([$key => $pkMeta], $fieldsMeta);
}
foreach ($fieldsMeta as $name => $fieldMeta)
{
/* @var $fieldMeta DocumentPropertyMeta */
if (array_key_exists($name, $data))
{
// Value is available in passed data
$value = $data[$name];
}
elseif (!empty($instance))
{
// Take value from existing instance
// NOTE: We could `continue` here but value should be sanitized anyway
$value = $model->$name;
}
else
{
// As a last resort set to default
$value = $fieldMeta->default;
}
if (!$filter->toModel($model, $fieldMeta))
{
continue;
}
$decorator->read($name, $value);
$model->$name = $sanitizer->read($name, $model->$name);
}
$md->read($data);
return FinalizingManager::toModel(static::class, $model);
}
protected static function getMeta(AnnotatedInterface $model)
{
return ManganMeta::create($model);
}
}
API documentation generated by ApiGen