diff --git a/administrator/components/com_admin/script.php b/administrator/components/com_admin/script.php
index f671cd7c208e3..132187cbb189c 100644
--- a/administrator/components/com_admin/script.php
+++ b/administrator/components/com_admin/script.php
@@ -9,6 +9,7 @@
defined('_JEXEC') or die;
+use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Extension\ExtensionHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Filesystem\File;
@@ -17,6 +18,8 @@
use Joomla\CMS\Language\Text;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Table\Table;
+use Joomla\CMS\Uri\Uri;
+use Joomla\Component\Config\Administrator\Model\ComponentModel;
use Joomla\Component\Fields\Administrator\Model\FieldModel;
use Joomla\Database\ParameterType;
@@ -6668,6 +6671,8 @@ public function postflight($action, $installer)
}
}
+ $this->convertBlogLayouts();
+
return true;
}
@@ -7029,4 +7034,147 @@ private function updateContentTypes(): void
$db->execute();
}
}
+
+ /**
+ * Converts layout parameters for blog / featured views into the according CSS classes.
+ *
+ * @return void
+ *
+ * @since 4.0.0
+ */
+ private function convertBlogLayouts()
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true)
+ ->select(
+ [
+ $db->quoteName('m.id'),
+ $db->quoteName('m.link'),
+ $db->quoteName('m.params'),
+ ]
+ )
+ ->from($db->quoteName('#__menu', 'm'))
+ ->leftJoin($db->quoteName('#__extensions', 'e'), $db->quoteName('e.extension_id') . ' = ' . $db->quoteName('m.component_id'))
+ ->where($db->quoteName('e.element') . ' = ' . $db->quote('com_content'));
+
+ $menuItems = $db->setQuery($query)->loadAssocList('id');
+ $contentParams = ComponentHelper::getParams('com_content');
+
+ foreach ($menuItems as $id => $menuItem)
+ {
+ $view = Uri::getInstance($menuItem['link'])->getVar('view');
+
+ if (!in_array($view, ['category', 'categories', 'featured']))
+ {
+ continue;
+ }
+
+ $params = json_decode($menuItem['params'], true);
+
+ // Don't update parameters if num_columns is unset.
+ if (!isset($params['num_columns']))
+ {
+ continue;
+ }
+
+ $useLocalCols = $params['num_columns'] !== '';
+
+ if ($useLocalCols)
+ {
+ $nColumns = (int) $params['num_columns'];
+ }
+ else
+ {
+ $nColumns = (int) $contentParams->get('num_columns', '1');
+ }
+
+ unset($params['num_columns']);
+
+ $order = 0;
+ $useLocalOrder = false;
+
+ if (isset($params['multi_column_order']))
+ {
+ if ($params['multi_column_order'] !== '')
+ {
+ $useLocalOrder = true;
+ $order = (int) $params['multi_column_order'];
+ }
+ else
+ {
+ $order = (int) $contentParams->get('multi_column_order', '0');
+ }
+
+ unset($params['multi_column_order']);
+ }
+
+ // Only add CSS class if columns > 1 and a local value was set for columns or order.
+ if ($nColumns > 1 && ($useLocalOrder || $useLocalCols))
+ {
+ // Convert to the according CSS class depending on order = "down" or "across".
+ $layout = ($order === 0) ? 'masonry-' : 'columns-';
+
+ if (strpos($params['blog_class'], $layout) === false)
+ {
+ $params['blog_class'] .= ' ' . $layout . $nColumns;
+ }
+ }
+
+ $newParams = json_encode($params);
+
+ $query = $db->getQuery(true)
+ ->update($db->quoteName('#__menu'))
+ ->set($db->quoteName('params') . ' = :params')
+ ->where($db->quoteName('id') . ' = :id')
+ ->bind(':params', $newParams, ParameterType::STRING)
+ ->bind(':id', $id, ParameterType::INTEGER);
+
+ $db->setQuery($query)->execute();
+ }
+
+ // Update global parameters for com_content.
+ $nColumns = $contentParams->get('num_columns');
+
+ if ($nColumns !== null || true)
+ {
+ $nColumns = (int) $nColumns;
+ $order = (int) $contentParams->get('multi_column_order', '0');
+ $params = $contentParams->toArray();
+
+ if (!isset($params['blog_class']))
+ {
+ $params['blog_class'] = '';
+ }
+
+ // Convert to the according CSS class depending on order = "down" or "across".
+ $layout = ($order === 0) ? 'masonry-' : 'columns-';
+
+ if (strpos($params['blog_class'], $layout) === false && $nColumns > 1)
+ {
+ $params['blog_class'] .= ' ' . $layout . $nColumns;
+ }
+
+ unset($params['num_columns']);
+
+ $app = Factory::getApplication();
+ /** @var ComponentModel $configModel */
+ $configModel = $app->bootComponent('com_config')
+ ->getMVCFactory()
+ ->createModel('Component', 'Administrator', ['ignore_request' => true]);
+
+ $query = $db->getQuery(true)
+ ->select($db->quoteName('extension_id'))
+ ->from($db->quoteName('#__extensions'))
+ ->where($db->quoteName('element') . ' = ' . $db->quote('com_content'));
+
+ $componentId = $db->setQuery($query)->loadResult();
+
+ $data = array(
+ 'id' => $componentId,
+ 'option' => 'com_content',
+ 'params' => $params,
+ );
+ $configModel->save($data);
+ }
+ }
}
diff --git a/administrator/components/com_content/config.xml b/administrator/components/com_content/config.xml
index eeff1565ebd14..d6de79d9c9294 100644
--- a/administrator/components/com_content/config.xml
+++ b/administrator/components/com_content/config.xml
@@ -714,6 +714,22 @@
label="COM_CONTENT_CONFIG_BLOG_SETTINGS_LABEL"
description="COM_CONTENT_CONFIG_BLOG_SETTINGS_DESC"
>
+
+
+
+