Last active
September 1, 2017 10:15
-
-
Save mdcpepper/454a3184e79d96da1b58c46f478c4e4f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Get the content of a field for use in BaseElementModel::setContentFromPost() | |
* | |
* @param BaseElementModel $sourceElement The element in the source locale | |
* @param BaseElementModel $targetElement The element in the target locale | |
* @param FieldModel $field The field to migrate | |
*/ | |
private function _getMigratedFieldContent(BaseElementModel $sourceElement, BaseElementModel $targetElement = null, FieldModel $field, $force = false) | |
{ | |
// If no target element has been passed, then we're getting the content for a new matrix | |
// block that doesn't yet exist on the target, so use the source element | |
if (!$targetElement) | |
{ | |
$targetElement = $sourceElement; | |
} | |
$fieldHandle = $field->handle; | |
$fieldType = $field->type; | |
$sourceLocale = $sourceElement->locale; | |
$targetLocale = $targetElement->locale; | |
// Determine which element to get the content from, source or target. | |
// If the targetElement already has content for this field, don't migrate | |
// anything and use its already-existing content | |
if ($this->_isEmpty($targetElement, $field) || !!$force) | |
{ | |
// The target element's content for this field is empty, or it's being forced, so pull the content from the source element | |
$element = $sourceElement; | |
} | |
else | |
{ | |
// The target element already has content set for this field, so use that | |
$element = $targetElement; | |
} | |
switch ($fieldType) | |
{ | |
// Fields that do not need any transforming and are returned as-is | |
case 'PlainText': | |
case 'Number': | |
case 'Lightswitch': | |
case 'PositionSelect': | |
{ | |
return $element->$fieldHandle; | |
} | |
// Checkboxes are returned as an array of selected values | |
case 'Checkboxes': | |
{ | |
$selected = array(); | |
foreach($element->$fieldHandle->getOptions() as $option) | |
{ | |
if ($option->selected) | |
{ | |
$selected[] = $option->value; | |
} | |
} | |
return $selected; | |
} | |
// Dropdown fields return their selected value | |
case 'Dropdown': | |
{ | |
if ($element->$fieldHandle) | |
{ | |
return $element->$fieldHandle->value; | |
} | |
} | |
// Dates are returned in MYSQL_DATETIME format | |
case 'Date': | |
{ | |
if ($element->$fieldHandle) | |
{ | |
return $element->$fieldHandle->format(DateTime::MYSQL_DATETIME); | |
} | |
} | |
// RichText fields return the raw content with reference tags intact | |
case 'RichText': | |
{ | |
if ($element->$fieldHandle instanceof RichTextData) | |
{ | |
return $element->$fieldHandle->getRawContent(); | |
} | |
} | |
// Matrix fields are a little more complicated.. | |
case 'Matrix': | |
{ | |
// to get all the content of the fields inside the Matrix | |
return $this->_getMatrixContent($element, $field, $sourceLocale, $targetLocale); | |
} | |
// Relation fields return an array of their related IDs | |
case 'Assets': | |
case 'Categories': | |
case 'Entries': | |
case 'Tags': | |
case 'Users': | |
{ | |
$ids = $element->$fieldHandle->ids(); | |
return empty($ids) ? null : $ids; | |
} | |
// Table fields return the col1, col2, etc values | |
case 'Table': | |
{ | |
$table = array(); | |
if ($element->$fieldHandle) | |
{ | |
foreach($element->$fieldHandle as $row) | |
{ | |
$newRow = array(); | |
$numCols = count($row) / 2; | |
for ($i=1; $i <= $numCols; $i++) | |
{ | |
$newRow['col'.$i] = $row['col'.$i]; | |
} | |
$table[] = $newRow; | |
} | |
} | |
return $table; | |
} | |
} | |
/** | |
* Returns the content for a matrix field | |
* | |
* @param BaseElementModel $element | |
* @param FieldModel $field | |
* @param string $targetLocale | |
* | |
* @return array An array of blocks, or just null | |
*/ | |
private function _getMatrixContent($element, $field, $targetLocale) | |
{ | |
$fieldHandle = $field->handle; | |
// There's no blocks at all | |
if (null === $element->$fieldHandle) | |
{ | |
return null; | |
} | |
$sourceBlocks = $element->$fieldHandle->status(null)->limit(null)->find(); | |
$targetBlocks = array(); | |
foreach($sourceBlocks as $index => $sourceBlock) | |
{ | |
// Set the properties of the new block | |
$targetBlock = array( | |
'type' => $sourceBlock->getType()->handle, | |
'enabled' => (bool) $sourceBlock->enabled, | |
'locale' => $targetLocale, | |
'fields' => array(), | |
); | |
// For each of the fields in the source block's field layout | |
foreach($sourceBlock->getFieldLayout()->getFields() as $fieldLayoutField) | |
{ | |
// Get the actual field | |
$field = $fieldLayoutField->getField(); | |
// And the field handle | |
$fieldHandle = $field->handle; | |
// Get the value of the field for use in setContentFromPost. | |
$targetBlock['fields'][$fieldHandle] = $this->_getMigratedFieldContent($sourceBlock, null, $field); | |
} | |
$targetBlocks["new".($index+1)] = $targetBlock; | |
} | |
return $targetBlocks; | |
} | |
/** | |
* Determine whether a field has any content or not | |
* | |
* @param BaseElementModel $element | |
* @param FieldModel $field | |
* | |
* @return bool Whether the field has any content or not | |
*/ | |
private function _isEmpty($element, FieldModel $field) | |
{ | |
$elementId = $element->id; | |
$fieldHandle = $field->handle; | |
$fieldType = $field->type; | |
// If accessing the field directly returns a true or empty response, | |
// it's safe to consider it empty | |
if (is_null($element->$fieldHandle) || empty($element->$fieldHandle)) | |
{ | |
//EmigratePlugin::log("\n\n".$fieldHandle." in ".$element->locale." is empty\n"); | |
return true; | |
} | |
// Relations / Matrix fields are empty if the result count is 0 | |
if ($element->$fieldHandle instanceof ElementCriteriaModel) | |
{ | |
if ($element->$fieldHandle->count() === 0) | |
{ | |
return true; | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
// Rich Text fields return a \Twig_Markup object | |
if ($fieldType == 'RichText') | |
{ | |
if ((string) TemplateHelper::getRaw($element->$fieldHandle) == '') | |
{ | |
return true; | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
// TODO: Allow for plugins to determine whether a field is empty or not | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment