Commit a4195dd2 authored by Robert Lyon's avatar Robert Lyon Committed by Aaron Wells
Browse files

upgrading problem from older version and view_layout table (bug 1224788)



Upgrading from an older version would fail because of the way view
layout table was dropped and then added again.

Changed it so the view layout table remains; old view layouts are
translated into new ones; and there's no longer any reliance
on the default records getting specific ID numbers when they are
inserted.

Change-Id: I48d01287ba689c9b3ad23bac7e6258c9e65f0e44
Signed-off-by: Robert Lyon's avatarRobert Lyon <robertl@catalyst.net.nz>
Signed-off-by: Aaron Wells's avatarAaron Wells <aaronw@catalyst.net.nz>
parent fb15e4d8
......@@ -678,8 +678,9 @@
<TABLE NAME="view_layout">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="rows" TYPE="int" LENGTH="1" NOTNULL="true"/>
<FIELD NAME="iscustom" TYPE="int" LENGTH="1" NOTNULL="true"/>
<FIELD NAME="rows" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="1"/>
<FIELD NAME="iscustom" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0"/>
<FIELD NAME="layoutmenuorder" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
......
......@@ -3229,13 +3229,7 @@ function xmldb_core_upgrade($oldversion=0) {
$table->addKeyInfo('viewfk', XMLDB_KEY_FOREIGN, array('view'), 'view', array('id'));
create_table($table);
// 2. Rename the table view_layout to view_layout_columns
$table = new XMLDBTable('view');
$key = new XMLDBKey('view_lay_fk');
$key->setAttributes(XMLDB_KEY_FOREIGN, array('layout'), 'view_layout', array('id'));
drop_key($table, $key);
$table = new XMLDBTable('view_layout');
drop_table($table);
// 2. Remake the table view_layout as view_layout_columns
$table = new XMLDBTable('view_layout_columns');
$table->addFieldInfo('id', XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL, XMLDB_SEQUENCE);
$table->addFieldInfo('columns', XMLDB_TYPE_INTEGER, 1, null, XMLDB_NOTNULL);
......@@ -3244,13 +3238,17 @@ function xmldb_core_upgrade($oldversion=0) {
$table->addKeyInfo('columnwidthuk', XMLDB_KEY_UNIQUE, array('columns', 'widths'));
create_table($table);
// 3. Create new table view_layout
// 3. Alter table view_layout
$table = new XMLDBTable('view_layout');
$table->addFieldInfo('id', XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL, XMLDB_SEQUENCE);
$table->addFieldInfo('rows', XMLDB_TYPE_INTEGER, 1, null, XMLDB_NOTNULL);
$table->addFieldInfo('iscustom', XMLDB_TYPE_INTEGER, 1, null, XMLDB_NOTNULL);
$table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
create_table($table);
$field = new XMLDBField('rows');
$field->setAttributes(XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL, null, null, null, 1);
add_field($table, $field);
$field = new XMLDBField('iscustom');
$field->setAttributes(XMLDB_TYPE_INTEGER, 1, null, XMLDB_NOTNULL, null, null, null, 0);
add_field($table, $field);
$field = new XMLDBField('layoutmenuorder');
$field->setAttributes(XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL, null, null, null, 0);
add_field($table, $field);
// 4. Create table view_layout_rows_columns
$table = new XMLDBTable('view_layout_rows_columns');
......@@ -3271,11 +3269,55 @@ function xmldb_core_upgrade($oldversion=0) {
$table->addKeyInfo('layoutfk', XMLDB_KEY_FOREIGN, array('layout'), 'view_layout', array('id'));
create_table($table);
// 6. Update default values for tables view_layout, view_layout_columns and view_layout_rows_columns
install_view_column_widths();
// 6. Convert existing view_layout records into new-style view_layouts with just one row
$oldlayouts = get_records_array('view_layout', '', '', 'id', 'id, columns, widths');
foreach ($oldlayouts as $layout) {
// We don't actually need to populate the "rows", "iscustom" or "layoutmenuorder" columns,
// because their defaults take care of that.
// Check to see if there's a view_layout_columns record that matches its widths.
$colsid = get_field('view_layout_columns', 'id', 'widths', $layout->widths);
if (!$colsid) {
$colsid = insert_record(
'view_layout_columns',
(object) array(
'columns' => $layout->columns,
'widths' => $layout->widths
),
'id',
true
);
}
// Now insert a record for it in view_layout_rows_columns, to represent its one row
insert_record(
'view_layout_rows_columns',
(object) array(
'viewlayout' => $layout->id,
'row' => 1,
'columns' => $colsid
)
);
// And also it needs a record in usr_custom_layout saying it belongs to the root user
insert_record('usr_custom_layout', (object)array(
'usr' => 0,
'layout' => $layout->id,
));
}
// 7. Now we can drop the obsolete view_layout.columns and view_layout.widths fields
$table = new XMLDBTable('view_layout');
$field = new XMLDBField('columns');
drop_field($table, $field);
$field = new XMLDBField('widths');
drop_field($table, $field);
// 8. Update default values for tables view_layout, view_layout_columns and view_layout_rows_columns
install_view_layout_defaults();
// 7. Update the table 'block_instance'
// 9. Update the table 'block_instance'
$table = new XMLDBTable('block_instance');
$field = new XMLDBField('row');
$field->setAttributes(XMLDB_TYPE_INTEGER, 2, null, XMLDB_NOTNULL, null, null, null, 1);
......@@ -3287,75 +3329,15 @@ function xmldb_core_upgrade($oldversion=0) {
$key->setAttributes(XMLDB_KEY_UNIQUE, array('view', 'row', 'column', 'order'));
add_key($table, $key);
// 8. Update the table 'view'
// 10. Add a "numrows" column to the views table. The default value of "1" will be correct
// for all existing views, because they're using the old one-row layout style
$table = new XMLDBTable('view');
$field = new XMLDBField('numrows');
$field->setAttributes(XMLDB_TYPE_INTEGER, 2, null, XMLDB_NOTNULL, null, null, null, 1);
add_field($table, $field);
$key = new XMLDBKey('layoutfk');
$key->setAttributes(XMLDB_KEY_FOREIGN, array('layout'), 'view_layout', array('id'));
add_key($table, $key);
// 9. Update the table 'view_rows_columns' for existing pages
// In the previous Mahara version, we applied the view layouts:
/*
id columns width
1 1 100
2 2 50,50
3 2 67,33
4 2 33,67
5 3 33,33,33
6 3 25,50,25
7 3 15,70,15
8 4 25,25,25,25
9 4 20,30,30,20
10 5 20,20,20,20,20
*/
// In this version, we introduced 2 more layouts (id=8 and 9)
/*
id columns width
1 1 100
2 2 50,50
3 2 67,33
4 2 33,67
5 3 33,33,33
6 3 25,50,25
7 3 25,25,50
8 3 50,25,25
9 3 15,70,15
10 4 25,25,25,25
11 4 20,30,30,20
12 5 20,20,20,20,20
*/
$sql = "
FROM {view} v";
$pwcount = count_records_sql("SELECT COUNT(v.id) " . $sql);
$sql = "
SELECT v.id, v.numcolumns, v.layout " . $sql . " WHERE v.id > ?
ORDER BY v.id";
$done = 0;
$lastid = 0;
$limit = 4000;
while ($views = get_records_sql_array($sql, array($lastid), 0, $limit)) {
foreach ($views as $view) {
$columns = $view->numcolumns;
if ($view->layout !== NULL) {
// Update the new layout in database
$layout = $view->layout;
if ($layout > 7) {
$layout += 2;
}
$newview = clone $view;
$newview->layout = $layout;
update_record('view', $newview);
}
insert_record('view_rows_columns', (object) array('view' => $view->id, 'row' => 1, 'columns' => $columns));
$lastid = $view->id;
}
$done += count($views);
log_debug("Upgrading pages: $done/$pwcount");
set_time_limit(30);
}
// 11. Update the table 'view_rows_columns' for existing pages
execute_sql('INSERT INTO {view_rows_columns} ("view", "row", "columns") SELECT v.id, 1, v.numcolumns FROM {view} v');
}
if ($oldversion < 2013091900) {
......
......@@ -608,7 +608,7 @@ function core_postinst() {
$key->setAttributes(XMLDB_KEY_FOREIGN, array('logo'), 'artefact', array('id'));
add_key($table, $key);
// PostgreSQL supports indexes over functions of columns, MySQL does not.
// PostgreSQL supports indexes over functions of columns, MySQL does not.
// We make use if this if we can
if (is_postgres()) {
// Improve the username index
......@@ -723,8 +723,6 @@ function core_install_lastcoredata_defaults() {
insert_record('usr', $user);
}
// install the view column widths
install_view_column_widths();
// install the default layout options
install_view_layout_defaults();
......@@ -1112,43 +1110,141 @@ function install_blocktype_extras() {
/**
* Installs all the allowed column widths for views. Used when installing core
* defaults, and also when upgrading from 0.8 to 0.9
* defaults, and also when upgrading from 1.7 to 1.8
*/
function install_view_column_widths() {
db_begin();
require_once('view.php');
$layout = new StdClass;
foreach (View::$layouts as $column => $widths) {
$layout = new stdClass();
$delayinserts = array();
$x = 0;
foreach (View::$basic_column_layouts as $column => $widths) {
foreach ($widths as $width) {
$layout->columns = $column;
$layout->widths = $width;
insert_record('view_layout_columns', $layout);
// If we're upgrading, then this width may already be present
// from the conversion of an exising layout.
if (!record_exists('view_layout_columns', 'widths', $width)) {
$layout = new stdClass();
$layout->columns = $column;
$layout->widths = $width;
insert_record('view_layout_columns', $layout);
}
}
}
db_commit();
}
function install_view_layout_defaults() {
db_begin();
require_once('view.php');
// Make sure all the column widths are present
install_view_column_widths();
// Fetch all the existing layouts so we can check below whether each default already exists
$oldlayouts = array();
$layoutrecs = get_records_assoc('view_layout', 'iscustom', '0', '', 'id, rows, iscustom');
if ($layoutrecs) {
foreach ($layoutrecs as $rec) {
$rows = get_records_sql_assoc(
'select vlrc.row, vlc.widths
from
{view_layout_rows_columns} vlrc
inner join {view_layout_columns} vlc
on vlrc.columns = vlc.id
where vlrc.viewlayout = ?
order by vlrc.row',
array($rec->id)
);
if (!$rows) {
// This layout has no rows. Strange, but let's just ignore it for now.
log_warn('view_layout ' . $rec->id . ' is missing its row or column width records.');
continue;
}
$allwidths = '';
foreach ($rows as $rowrec) {
$allwidths .= $rowrec->widths . '-';
}
// Drop the last comma
$allwidths = substr($allwidths, 0, -1);
$oldlayouts[$rec->id] = $allwidths;
}
}
foreach (View::$defaultlayoutoptions as $id => $rowscols) {
$vlid = insert_record('view_layout', (object)array(
'iscustom' => 0,
'rows' => count($rowscols),
), 'id', true);
insert_record('usr_custom_layout', (object)array(
'usr' => 0,
'layout' => $vlid,
));
// Check to see whether it matches an existing record
$allwidths = '';
$numrows = 0;
foreach ($rowscols as $row => $col) {
if ($row != 'order') {
$allwidths .= $col . '-';
$numrows++;
}
}
$allwidths = substr($allwidths, 0, -1);
$found = array_search($allwidths, $oldlayouts);
if ($found !== false) {
// There's a perfect match in the DB already. Just make sure it has the right menu order
if (isset($rowscols['order'])) {
update_record(
'view_layout',
(object)array(
'id' => $found,
'layoutmenuorder'=>$rowscols['order']
)
);
}
continue;
}
// It doesn't exist yet! So, set it up.
$vlid = insert_record(
'view_layout',
(object)array(
'iscustom' => 0,
'rows' => $numrows,
'layoutmenuorder' => (isset($rowscols['order']) ? $rowscols['order'] : 0)
),
'id',
true
);
insert_record(
'usr_custom_layout',
(object)array(
'usr' => 0,
'layout' => $vlid,
)
);
foreach ($rowscols as $row => $col) {
insert_record('view_layout_rows_columns', (object)array(
'viewlayout' => $id,
'row' => $row,
'columns' => $col,
));
// The 'order' field indicates menu order if this layout is meant to be present
// in the default layout menu
if ($row == 'order') {
continue;
}
// Check for the ID of the column widths that match this row
$colsid = get_field('view_layout_columns', 'id', 'widths', $col);
if (!$colsid) {
// For some reason this layout_columns wasn't present yet.
// We'll just insert it, but also throw a warning
$colsid = insert_record(
'view_layout_columns',
(object) array(
'columns' => substr_count($col, ','),
'widths' => $col
),
'id',
true
);
log_warn('Default layout option ' . $id . ' uses a column set that is not present in the list of default column widths.');
}
insert_record(
'view_layout_rows_columns',
(object)array(
'viewlayout' => $vlid,
'row' => $row,
'columns' => $colsid,
)
);
}
}
......
......@@ -78,13 +78,27 @@ class View {
private $urlid;
private $skin;
/**
* Which view layout is considered the "default" for views with the given
* number of columns. Must be present in $layouts of course.
*/
public static $defaultcolumnlayouts = array(
1 => '100',
2 => '50,50',
3 => '33,33,33',
4 => '25,25,25,25',
5 => '20,20,20,20,20',
);
/**
* Valid view column layouts. These are read at install time and inserted into
* view_layout_columns, but not updated afterwards, so if you're changing one
* you'll need to do that manually.
* A hash of columns => list of view widths
*
* The key represents the number of columns, and the value is an array of all the
* view_layout_columns records that have that number of columns
*/
public static $layouts = array(
public static $basic_column_layouts = array(
1 => array(
'100',
),
......@@ -109,109 +123,110 @@ class View {
),
);
/**
* Which view layout is considered the "default" for views with the given
* number of columns. Must be present in $layouts of course.
*/
public static $defaultcolumnlayouts = array(
1 => '100',
2 => '50,50',
3 => '33,33,33',
4 => '25,25,25,25',
5 => '20,20,20,20,20',
);
/**
* The default layout options to be read at install time.
* Each view_layout record is based on the array key and the count of its values.
* Each view_layout_rows_columns record is based on the sub array.
* For example:
* 18 => array(
* 1 => 1,
* 2 => 2,
* 3 => 1
* ),
* 1 => '100',
* 2 => '50,50',
* 3 => '100'
* 'order' => 3
* ),
* will insert a record in view_layout with id = 18 and rows = 3
* and will insert 3 records in view_layout_rows_columns:
* - viewlayout = 18, rows = 1, columns = 1
* - viewlayout = 18, rows = 2, columns = 2
* - viewlayout = 18, rows = 3, columns = 1
* And the "order" key indicates that this should be the 3rd option in the layout menu
*/
public static $defaultlayoutoptions = array(
1 => array(
1 => 1
1 => '100',
'order' => 1,
),
2 => array(
1 => 2
1 => '50,50',
'order' => 2,
),
3 => array(
1 => 3
1 => '67,33',
'order' => 3,
),
4 => array(
1 => 4
1 => '33,67',
'order' => 4,
),
5 => array(
1 => 5
1 => '33,33,33',
'order' => 5,
),
6 => array(
1 => 6
1 => '25,50,25',
'order' => 6,
),
7 => array(
1 => 7
1 => '25,25,50'
),
8 => array(
1 => 8
1 => '50,25,25'
),
9 => array(
1 => 9
1 => '15,70,15'
),
10 => array(
1 => 10
1 => '25,25,25,25'
),
11 => array(
1 => 11
1 => '20,30,30,20'
),
12 => array(
1 => 12
1 => '20,20,20,20,20'
),
13 => array(
1 => 1,
2 => 6
1 => '100',
2 => '25,50,25'
),
14 => array(
1 => 1,
2 => 4
1 => '100',
2 => '33,67',
'order' => 7
),
15 => array(
1 => 1,
2 => 3
1 => '100',
2 => '67,33'
),
16 => array(
1 => 1,
2 => 2
1 => '100',
2 => '50,50'
),
17 => array(
1 => 1,
2 => 5
1 => '100',
2 => '33,33,33',
'order' => 8
),
18 => array(
1 => 1,
2 => 2,
3 => 1
1 => '100',
2 => '50,50',
3 => '100'
),
19 => array(
1 => 1,
2 => 5,
3 => 1
1 => '100',
2 => '33,33,33',
3 => '100',
'order' => 9
),
20 => array(
1 => 1,
2 => 6,
3 => 1
1 => '100',
2 => '25,50,25',
3 => '100'
),
21 => array(
1 => 1,
2 => 2,
3 => 5
1 => '100',
2 => '50,50',
3 => '33,33,33',
'order' => 10
),
);
......
......@@ -50,7 +50,15 @@ $numcolumns = $view->get('numcolumns');
$layoutcolumns = View::$layoutcolumns; // static, all possible column width combinations
$layoutrows = $view->get_layoutrows();
$maxlayoutrows = View::$maxlayoutrows; // static, max possible rows for custom layouts
$basicoptionids = array(1,2,3,4,5,6,14,17,19,21); // most commonly used layouts - present these as basic option
$basicoptionids = array_keys(
get_records_select_assoc(
'view_layout',
'layoutmenuorder > 0 AND iscustom = 0',
array(),
'layoutmenuorder',
'id, id'
)
);
$currentlayout = $view->get('layout');
// if not set, use equal width layout for that number of columns
if (!$currentlayout) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment