Skip to content

Commit

Permalink
refactor: Initial JSON query work
Browse files Browse the repository at this point in the history
  • Loading branch information
khalwat committed Feb 5, 2024
1 parent ab1042f commit be2040c
Showing 1 changed file with 68 additions and 4 deletions.
72 changes: 68 additions & 4 deletions src/services/Assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

use Craft;
use craft\base\FieldInterface;
use craft\db\Query;
use craft\db\Table;
use craft\fields\Matrix;
use craft\helpers\Db;
use craft\helpers\ElementHelper;
use craft\helpers\Json;
use lsst\cantodamassets\fields\CantoDamAsset;
use lsst\cantodamassets\lib\laravel\Collection;
use lsst\cantodamassets\models\CantoFieldData;
Expand Down Expand Up @@ -167,21 +169,66 @@ protected function updateContent(string $value, CantoFieldData $cantoFieldData,
{
$columnKey = self::CONTENT_COLUMN_KEY_MAPPINGS[$columnKey] ?? null;
foreach ($cantoDamAssetFields as $cantoDamAssetField) {
// Find any $queryColumn content column row that match $value, and update them with the data from $cantoFieldData
$queryColumn = ElementHelper::fieldColumnFromField($cantoDamAssetField, $columnKey);
$columns = [];
foreach (self::CONTENT_COLUMN_KEY_MAPPINGS as $propertyName => $selectColumnKey) {
$columns[ElementHelper::fieldColumnFromField($cantoDamAssetField, $selectColumnKey)] = $cantoFieldData->$propertyName;
}
if ($queryColumn) {
$columns = $this->getColumns($cantoDamAssetField, $cantoFieldData);
try {
$rows = Db::update($table, $columns, [$queryColumn => $value]);
} catch (Exception $e) {
Craft::error($e->getMessage(), __METHOD__);
}
}
// If the column we're updating is the `cantoId`, we need to search the JSON contents of `cantoAssetData`
// in order to update any canto assets contained within the JSON blobs as well
if ($columnKey === 'cantoId') {

Check failure on line 184 in src/services/Assets.php

View workflow job for this annotation

GitHub Actions / PHPStan

Strict comparison using === between 'cantoAlbumData'|'cantoAlbumId'|'cantoAssetData'|null and 'cantoId' will always evaluate to false.
$db = Craft::$app->getDb();
// Get any existing Canto Assets fields that contain the asset ID we're updating
$cantoIdFieldName = ElementHelper::fieldColumnFromField($cantoDamAssetField, self::CONTENT_COLUMN_KEY_MAPPINGS['cantoId']);
$cantoAssetDataFieldName = ElementHelper::fieldColumnFromField($cantoDamAssetField, self::CONTENT_COLUMN_KEY_MAPPINGS['cantoAssetData']);
$jsonSearchNeedle = ['id' => $cantoFieldData->cantoId];
$jsonSearchSql = '';
if ($db->getIsMysql()) {
$jsonSearchSql = $this->mySqlJsonContains($cantoAssetDataFieldName, $jsonSearchNeedle);
}
if ($db->getIsPgsql()) {
$jsonSearchSql = $this->pgSqlJsonContains($cantoAssetDataFieldName, $jsonSearchNeedle);
}
$rows = (new Query())
->select([$cantoAssetDataFieldName])
->from([$table])
->where([$cantoIdFieldName => 0, $cantoAssetDataFieldName => $jsonSearchSql])
->all();
}
}
}

/**
* Return a jsonContains expression properly formatted for MySQL
*
* @param string $targetSql
* @param mixed $value
* @return string
*/
private function mySqlJsonContains(string $targetSql, mixed $value): string
{
$value = Craft::$app->getDb()->quoteValue(Json::encode($value));
return "JSON_CONTAINS($targetSql, $value)";
}

/**
* Return a jsonContains expression properly formatted for Postgres
*
* @param string $targetSql
* @param mixed $value
* @return string
*/
private function pgSqlJsonContains(string $targetSql, mixed $value): string
{
$value = Craft::$app->getDb()->quoteValue(Json::encode($value));
return "($targetSql @> $value::jsonb)";
}

/**
* Block type fields have the same methods as Matrix
*
Expand All @@ -193,4 +240,21 @@ private function getBlockFields(string $fieldType): array
/** @phpstan-ignore-next-line */
return Craft::$app->getFields()->getFieldsByType($fieldType);
}

/**
* Return the $cantoDamAssetField db columns to update with the values from the $cantoFieldData
*
* @param FieldInterface $cantoDamAssetField
* @param CantoFieldData $cantoFieldData
* @return array
*/
private function getColumns(FieldInterface $cantoDamAssetField, CantoFieldData $cantoFieldData): array
{
$columns = [];
foreach (self::CONTENT_COLUMN_KEY_MAPPINGS as $propertyName => $selectColumnKey) {
$columns[ElementHelper::fieldColumnFromField($cantoDamAssetField, $selectColumnKey)] = $cantoFieldData->$propertyName;
}

return $columns;
}
}

0 comments on commit be2040c

Please sign in to comment.