CakePHP 3.5 Всегда применять функцию MySQL asText () к пространственному полю

У меня есть обычай PolygonType который представляет собой POLYGON() поле в таблице MySQL.

class PolygonType extends BaseType implements ExpressionTypeInterface
{
public function toPHP($value, Driver $d)
{
// $value is binary, requires unpack()
}
}

я могу использовать $query->func()->astext() на каждый найти, но хотелось бы узнать, возможно ли всегда применять MySQL AsText() функция при выборе этого поля вместо (аналогично тому, как toExpression() можно использовать при вставке данных).

0

Решение

У AFAIK такой функциональности нет, классы типов и содержимое предложения select никогда не трогают.

Если вы хотите применить это ко всем находкам, то вы можете, например, использовать Model.beforeFind() событие, пройти через select и преобразовать поля в выражения. Вот быстрый и грязный пример, где field это имя POLYGON тип столбца:

// in the respective table class

use Cake\Event\Event;
use Cake\ORM\Query;

// ...

public function beforeFind(Event $event, Query $query, \ArrayObject $options, $primary)
{
$query->traverse(
function (&$value) use ($query) {
if (empty($value)) {
$value = $query->aliasFields($this->getSchema()->columns());
}

foreach ($value as $key => $field) {
if (is_string($field) &&
$this->aliasField($field) === $this->aliasField('field')
) {
unset($value[$key]);
$value[key($query->aliasField($field))] = $query->func()->AsText([
$this->aliasField('field') => 'identifier'
]);
}
}
},
['select']
);
}

Возможно, вам придется учитывать $field в качестве выражений тоже, в случае, если поле может использоваться в одном и должно быть преобразовано там же.

Другой способ — преобразовать данные на уровне PHP в класс типов. toPHP() метод, как уже указано в вашем примере кода.

Смотрите также

1

Другие решения

На основе NDP«s ответ, можно проверить типы полей через $query->getDefaultTypes() и применить функцию SQL, как требуется. Тем не мение, $value пусто, если поля изначально не указаны (например, при использовании Table::get() так что есть и проверка для этого.

public function beforeFind(Event $event, Query $query, ArrayObject $options, $primary)
{
$query->traverse(
function (&$value) use ($query) {

if (is_array($value) && empty($value)) {
$query->all();
}

$defaultTypes = $query->getDefaultTypes();

foreach ($value as $key => $field) {
if (in_array($defaultTypes[$field], ['point', 'polygon'])) {
$value[$key] = $query->func()->astext([
$this->aliasField($field) => 'identifier'
]);
}
}

$query->select($value);
},
['select']
);
}
0

По вопросам рекламы [email protected]