Skip to content

Instantly share code, notes, and snippets.

@ttempleton
Last active April 11, 2019 12:41
Show Gist options
  • Save ttempleton/526ea85084c58a72c8428990ed5e5022 to your computer and use it in GitHub Desktop.
Save ttempleton/526ea85084c58a72c8428990ed5e5022 to your computer and use it in GitHub Desktop.
Move Neo-specific Relabel data from Craft 2 to Craft 3 based on field/block type handles
<?php
namespace craft\contentmigrations;
use Craft;
use craft\db\Migration;
use craft\db\Query;
use spicyweb\fieldlabels\Plugin as FieldLabels;
use spicyweb\fieldlabels\models\FieldLabel as FieldLabelModel;
/**
* m190411_114426_importneorelabeldata migration.
* Reads `config/neorelabeldata.json`, tries to find the fields and field layouts based on the field and block type
* handles from the label data and, if they were found, saves the label to the database.
*/
class m190411_114426_importneorelabeldata extends Migration
{
/**
* @var array
*/
private $_layoutMap = [];
/**
* @var array
*/
private $_fieldMap = [];
/**
* @inheritdoc
*/
public function safeUp()
{
$pluginsService = Craft::$app->getPlugins();
$fieldsService = Craft::$app->getFields();
$dataPath = Craft::$app->getConfig()->configDir . DIRECTORY_SEPARATOR . 'neorelabeldata.json';
if (!(file_exists($dataPath) && $pluginsService->isPluginInstalled('fieldlabels') && $pluginsService->isPluginInstalled('neo'))) {
return false;
}
$contents = file_get_contents($dataPath);
$labelData = json_decode($contents);
foreach ($labelData as $label) {
$fieldId = $this->_getFieldId($label->relabelledField);
$fieldLayoutId = $this->_getFieldLayoutId($label->neoField, $label->blockType);
if ($fieldId !== null && $fieldLayoutId !== null) {
$newLabel = new FieldLabelModel;
$newLabel->fieldId = $fieldId;
$newLabel->fieldLayoutId = $fieldLayoutId;
foreach (['name', 'instructions'] as $prop) {
if ($label->$prop) {
$newLabel->$prop = $label->$prop;
}
}
FieldLabels::$plugin->methods->saveLabel($newLabel);
}
}
}
/**
* @inheritdoc
*/
public function safeDown()
{
echo "m190411_114426_importneorelabeldata cannot be reverted.\n";
return false;
}
/**
* Returns the field layout ID for the given Neo field and block type handles, if they exist.
*
* @param $neoFieldHandle
* @param $neoBlockTypeHandle
* @return int|null
*/
private function _getFieldLayoutId($neoFieldHandle, $neoBlockTypeHandle)
{
// Check the map
foreach ($this->_layoutMap as $layoutId => $neoFieldData) {
if ($neoFieldHandle === $neoFieldData['field'] && $neoBlockTypeHandle === $neoFieldData['blockType']) {
return $layoutId;
}
}
// Try the DB?
$neoFieldId = $this->_getFieldId($neoFieldHandle);
if ($neoFieldId !== null) {
$blockType = (new Query())
->select(['fieldLayoutId'])
->from(['{{%neoblocktypes}}'])
->where([
'fieldId' => $neoFieldId,
'handle' => $neoBlockTypeHandle,
])
->one();
if ($blockType && $blockType['fieldLayoutId'] !== null) {
$this->_layoutMap[$blockType['fieldLayoutId']] = [
'field' => $neoFieldHandle,
'blockType' => $neoBlockTypeHandle,
];
return $blockType['fieldLayoutId'];
}
}
// Nah
return null;
}
/**
* Returns the field ID for the given handle, if it exists.
*
* @param $handle
* @return int|null
*/
private function _getFieldId($handle)
{
// Check the map
foreach ($this->_fieldMap as $fieldHandle => $fieldId) {
if ($handle === $fieldHandle) {
return $fieldId;
}
}
// DB?
$field = Craft::$app->getFields()->getFieldByHandle($handle);
if ($field !== null) {
$this->_fieldMap[$handle] = $field->id;
return $field->id;
}
// No can do
return null;
}
}
<?php
namespace Craft;
/**
* Finds Relabel data associated with Neo fields and saves them to `craft/config/neorelabeldata.json`
*/
class NeoFieldRelabelDataPlugin extends BasePlugin
{
public function getName()
{
return 'Neo Field Relabel Data JSON';
}
public function getVersion()
{
return '1.0.0';
}
public function getDeveloper()
{
return 'Thomas Templeton';
}
public function getDeveloperUrl()
{
return 'https://github.com/ttempleton';
}
public function init()
{
parent::init();
if (craft()->request->isCpRequest()) {
$this->_getNeoRelabelData();
}
}
private function _getNeoRelabelData()
{
$neoRelabelDataPath = CRAFT_CONFIG_PATH . 'neorelabeldata.json';
if (!IOHelper::fileExists($neoRelabelDataPath)) {
$allNeoRelabelData = [];
$allRelabelLabels = craft()->relabel->getAllLabels();
foreach ($allRelabelLabels as $label) {
$blockTypeResult = craft()->db->createCommand()
->select('handle, fieldId')
->from('neoblocktypes')
->where('fieldLayoutId = :fieldLayoutId', [':fieldLayoutId' => $label->fieldLayoutId])
->queryRow();
if ($blockTypeResult) {
$relabelledField = craft()->fields->getFieldById($label->fieldId);
$neoField = craft()->fields->getFieldById($blockTypeResult['fieldId']);
$allNeoRelabelData[] = [
'name' => $label->name,
'instructions' => $label->instructions,
'relabelledField' => $relabelledField->handle,
'neoField' => $neoField->handle,
'blockType' => $blockTypeResult['handle'],
];
}
}
IOHelper::writeToFile($neoRelabelDataPath, json_encode($allNeoRelabelData));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment