/** * Load rows from table $tableName * @access private * * @param string $tableName Name of table (for error strings) * @param string $indexName * @param string $indexValue * @param string $indexValueType * @return boolean */ function loadRows($tableName, $indexName, $indexValue, $indexValueType) { $sql = 'SELECT * FROM ' . $this->_db->NameQuote($tableName); if ($indexName) { $sql .= "\n WHERE " . $this->_db->NameQuote($indexName) . ' = ' . $this->_sqlCleanQuote($indexValue, $indexValueType); } $this->_db->setQuery($sql); $result = $this->_db->loadObjectList(); if ($this->_db->getErrorMsg()) { $this->_setError(sprintf('%s::loadRows of Table %s Rows %s = %s failed with SQL error: %s', get_class($this), $tableName, $indexName, $this->_sqlCleanQuote($indexValue, $indexValueType), $this->_db->getErrorMsg()), $sql); return false; } else { // $this->_setLog( sprintf( 'Table %s Rows %s = %s successfully loaded', $tableName, $columnName, $this->_sqlCleanQuote( $indexValue, $indexValueType ) ), $sql, 'change' ); return $result; } }
function _fixCBmandatoryDb( $dryRun ) { cbimport( 'cb.sql.upgrader' ); $this->_sqlUpgrader = new CBSQLupgrader( $this->_db, $this->_silentWhenOK ); $this->_sqlUpgrader->setDryRun( $dryRun ); $sql = 'SELECT * FROM `#__comprofiler_tabs` ORDER BY `tabid`'; // `tabid`, `pluginclass` $this->_db->setQuery( $sql ); $tabs = $this->_db->loadObjectList( 'tabid' ); if ( $this->_db->getErrorNum() ) { $this->_sqlUpgrader->_setError( 'Tabs selection query error: ' . $this->_db->getErrorMsg() ); return false; } $sql = 'SELECT `fieldid`, `tabid` FROM `#__comprofiler_fields` ORDER BY `tabid`'; $this->_db->setQuery( $sql ); $fields = $this->_db->loadObjectList( 'fieldid' ); if ( $this->_db->getErrorNum() ) { $this->_sqlUpgrader->_setError( sprintf( 'Fields selection query error: ' . $this->_db->getErrorMsg() ), $sql ); return false; } // 1) count and index tabs by core pluginclass and tabid holding array of fieldsids, so we can delete empty duplicate core tabs: $coreTabs = array(); foreach ( $tabs as $t ) { if ( in_array( $t->pluginclass, $this->_tabsShouldBe ) ) { $coreTabs[$t->pluginclass][$t->tabid] = array(); } } // 2) group fieldids by tabid // 3) add fields to $coreTabs[pluginclass][tabid][fieldid] $tabsFields = array(); foreach ( $fields as $f ) { if ( isset( $tabs[$f->tabid] ) ) { $tabsFields[$f->tabid][$f->fieldid] = $f->fieldid; if ( $tabs[$f->tabid]->pluginclass != '' ) { $coreTabs[$tabs[$f->tabid]->pluginclass][$f->tabid][$f->fieldid] = $f->fieldid; } } } // 4) delete empty duplicate core tabs according to $coreTabs[pluginclass][tabid][fieldid] foreach ( $coreTabs as /* $pluginClass => */ $tabIds ) { if ( count( $tabIds ) > 1 ) { // there is more than one core tab for this core plugin class ! We need to decide which to keep: $tabidCandidatesToKeep = array(); // 1st priority: keep tabs that are enabled AND have fields: foreach ( $tabIds as $tId => $tFields ) { if ( ( $tabs[$tId]->enabled == 1 ) && ( count( $tFields ) > 0 ) ) { $tabidCandidatesToKeep[] = $tId; } } // 2nd priority: keep tabs that have fields: if ( count( $tabidCandidatesToKeep ) == 0 ) { foreach ( $tabIds as $tId => $tFields ) { if ( count( $tFields ) > 0 ) { $tabidCandidatesToKeep[] = $tId; } } } // 3rd priority: keep tabs that are enabled: if ( count( $tabidCandidatesToKeep ) == 0 ) { foreach ( $tabIds as $tId => $tFields ) { if ( $tabs[$tId]->enabled == 1 ) { $tabidCandidatesToKeep[] = $tId; } } } // 4th priority: keep tab with the correct id: if ( count( $tabidCandidatesToKeep ) == 0 ) { foreach ( $tabIds as $tId => $tFields ) { if ( isset( $this->_tabsShouldBe[$tId] ) && ( $tabs[$tId]->pluginclass == $this->_tabsShouldBe[$tId] ) ) { $tabidCandidatesToKeep[] = $tId; } } } // 5th priority: well no more priorities to think of ! : just take first one ! if ( count( $tabidCandidatesToKeep ) == 0 ) { foreach ( $tabIds as $tId => $tFields ) { $tabidCandidatesToKeep[] = $tId; break; } } // ok, by now we got at least one tab to keep: let's see which, in case we got more than one: if ( count( $tabidCandidatesToKeep ) == 1 ) { $tabToKeep = (int) $tabidCandidatesToKeep[0]; } else { $tabToKeep = null; // a) has the right core id: foreach ( $tabidCandidatesToKeep as $tId ) { if ( isset( $this->_tabsShouldBe[$tId] ) && ( $tabs[$tId]->pluginclass == $this->_tabsShouldBe[$tId] ) ) { $tabToKeep = $tId; break; } } // b) first with fields: if ( $tabToKeep === null ) { foreach ( $tabidCandidatesToKeep as $tId ) { if ( count( $coreTabs[$tabs[$tId]->pluginclass][$tId] ) > 0 ) { $tabToKeep = $tId; break; } } } // c) first enabled one: if ( $tabToKeep === null ) { foreach ( $tabidCandidatesToKeep as $tId ) { if ( $tabs[$tId]->enabled == 1 ) { $tabToKeep = $tId; break; } } } // d) first one: if ( $tabToKeep === null ) { foreach ( $tabidCandidatesToKeep as $tId ) { $tabToKeep = $tId; break; } } } if ( $tabToKeep !== null ) { $tabsToDelete = array_diff( array_keys( $tabIds ), array( $tabToKeep ) ); // first reassign the fields of the tabs to delete: $fieldsToReassign = array(); foreach ( $tabIds as $tId => $tFields ) { if ( ( $tId != $tabToKeep ) && count( $tFields ) > 0 ) { $fieldsToReassign = array_merge( $fieldsToReassign, $tFields ); } } if ( count( $fieldsToReassign ) > 0 ) { cbArrayToInts( $fieldsToReassign ); $sql = 'UPDATE `#__comprofiler_fields` SET `tabid` = ' . (int) $tabToKeep . ' WHERE `fieldid` IN (' . implode( ',', $fieldsToReassign ) . ')'; if ( ! $this->_sqlUpgrader->_doQuery( $sql ) ) { $this->_sqlUpgrader->_setError( 'Failed changing fieldids ' . implode( ',', $fieldsToReassign ) . ' from duplicates of kept core tabid: ' . $tabToKeep . ' because of error:' . $this->_db->getErrorMsg(), $sql ); break; } else { $this->_sqlUpgrader->_setLog( 'Changed fieldids ' . implode( ',', $fieldsToReassign ) . ' from duplicates of kept core tabid: ' . $tabToKeep, $sql, 'change' ); } } cbArrayToInts( $tabsToDelete ); // c) remove duplicate core tabs: $sql = 'DELETE FROM `#__comprofiler_tabs` WHERE `tabid` IN (' . implode( ',', $tabsToDelete ) . ')'; if ( ! $this->_sqlUpgrader->_doQuery( $sql ) ) { $this->_sqlUpgrader->_setError( 'Failed deleting duplicates tabids ' . implode( ',', $tabsToDelete ) . ' of the used core tabid: ' . $tabToKeep . ' because of error:' . $this->_db->getErrorMsg(), $sql ); break; } else { $this->_sqlUpgrader->_setLog( 'Deleted duplicate core tabs tabids ' . implode( ',', $tabsToDelete ) . ' of the used core tabid: ' . $tabToKeep, $sql, 'change' ); } } } } // 5) refetch tabs with now free space at reserved positions: $sql = 'SELECT * FROM `#__comprofiler_tabs` ORDER BY `tabid`'; // `tabid`, `pluginclass` $this->_db->setQuery( $sql ); $tabs = $this->_db->loadObjectList( 'tabid' ); if ( $this->_db->getErrorNum() ) { $this->_sqlUpgrader->_setError( 'Tabs 2nd selection query error: ' . $this->_db->getErrorMsg(), $sql ); return false; } unset( $coreTabs ); // this one is now invalid, and not needed anymore $sql = 'SELECT `fieldid`, `tabid` FROM `#__comprofiler_fields` ORDER BY `tabid`'; $this->_db->setQuery( $sql ); $fields = $this->_db->loadObjectList( 'fieldid' ); if ( $this->_db->getErrorNum() ) { $this->_sqlUpgrader->_setError( 'Fields 3nd selection query error: ' . $this->_db->getErrorMsg(), $sql ); return false; } // group fieldids by tabid $tabsFields = array(); foreach ( $fields as $f ) { if ( isset( $tabs[$f->tabid] ) ) { $tabsFields[$f->tabid][$f->fieldid] = $f->fieldid; } } // 6) check tabs one by one, making room in reserved positions: foreach ( $tabs as $t ) { if ( isset( $this->_tabsShouldBe[$t->tabid] ) && ( $t->pluginclass == $this->_tabsShouldBe[$t->tabid] ) ) { // ok, cool, tabid and plugin matches: no corrective action: continue; } if ( isset( $this->_tabsShouldBe[$t->tabid] ) ) { // not ok: tabid is taken by another tab: we need to relocate this tab at last position: // a) insert same tab in another tabid $oldTabId = $t->tabid; if ( ! $dryRun ) { $t->tabid = null; if ( ! $this->_db->insertObject( '#__comprofiler_tabs', $t, 'tabid' ) ) { $this->_sqlUpgrader->_setError( 'Failed moving (inserting) non-core tabid: ' . $oldTabId . ' because of error:' . $this->_db->getErrorMsg(), $sql ); break; } $t->tabid = $this->_db->insertid(); } else { $t->tabid = $t->tabid + 10000; // just to fake the insert } $this->_sqlUpgrader->_setLog( 'Inserted old tabid ' . $oldTabId . ' as new tabid ' . $t->tabid, ( $dryRun ? 'INSERT tabobject' : $this->_db->getQuery() ), 'change' ); // b) change fields' tabid: if ( isset( $tabsFields[$oldTabId] ) && ( count( $tabsFields[$oldTabId] ) > 0 ) ) { $sql = 'UPDATE `#__comprofiler_fields` SET `tabid` = ' . (int) $t->tabid . ' WHERE `tabid` = ' . (int) $oldTabId; if ( ! $this->_sqlUpgrader->_doQuery( $sql ) ) { $this->_sqlUpgrader->_setError( 'Failed changing fields from old non-core tab with core tabid: ' . $oldTabId . ' to new tabid: ' . $t->tabid . ' because of error:' . $this->_db->getErrorMsg(), $sql ); break; } else { $this->_sqlUpgrader->_setLog( 'Changed fields from old non-core tab with core tabid: ' . $oldTabId . ' (that must be for ' . $this->_tabsShouldBe[$oldTabId] . ') to new tabid: ' . $t->tabid, $sql, 'change' ); } } // c) remove old tab: $sql = 'DELETE FROM `#__comprofiler_tabs` WHERE tabid = ' . (int) $oldTabId; if ( ! $this->_sqlUpgrader->_doQuery( $sql ) ) { $this->_sqlUpgrader->_setError( 'Failed deleting old non-core tabid: ' . $oldTabId . ' which is already copied to new tabid: ' . $t->tabid . ' because of error:' . $this->_db->getErrorMsg(), $sql ); break; } else { $this->_sqlUpgrader->_setLog( 'Deleted old non-core tabid: ' . $oldTabId . ' which is already copied to new tabid: ' . $t->tabid, $sql, 'change' ); } } } // 7) refetch tabs with now free space at reserved positions as well as fields and recompute $tabFields: $sql = 'SELECT * FROM `#__comprofiler_tabs` ORDER BY `tabid`'; // `tabid`, `pluginclass` $this->_db->setQuery( $sql ); $tabs = $this->_db->loadObjectList( 'tabid' ); if ( $this->_db->getErrorNum() ) { $this->_sqlUpgrader->_setError( 'Tabs 3rd selection query error: ' . $this->_db->getErrorMsg(), $sql ); return false; } $sql = 'SELECT `fieldid`, `tabid` FROM `#__comprofiler_fields` ORDER BY `tabid`'; $this->_db->setQuery( $sql ); $fields = $this->_db->loadObjectList( 'fieldid' ); if ( $this->_db->getErrorNum() ) { $this->_sqlUpgrader->_setError( 'Fields 3nd selection query error: ' . $this->_db->getErrorMsg(), $sql ); return false; } // group fieldids by tabid $tabsFields = array(); foreach ( $fields as $f ) { if ( isset( $tabs[$f->tabid] ) ) { $tabsFields[$f->tabid][$f->fieldid] = $f->fieldid; } } // 8) check tabs one by one, moving tabs back to reserved positions if needed: foreach ( $tabs as $t ) { if ( isset( $this->_tabsShouldBe[$t->tabid] ) && ( $t->pluginclass == $this->_tabsShouldBe[$t->tabid] ) ) { // ok, cool, tabid and plugin matches: no corrective action: continue; } if ( ( ! isset( $this->_tabsShouldBe[$t->tabid] ) ) && in_array( $t->pluginclass, $this->_tabsShouldBe ) ) { // ok we found a core CB tab which doesn't have the right id: the right id is now free, so just update the tab: $newTabId = array_search( $t->pluginclass, $this->_tabsShouldBe ); if ( $newTabId !== false ) { // a) move the core tab to the right tabid: $sql = 'UPDATE `#__comprofiler_tabs` SET `tabid` = ' . (int) $newTabId . ' WHERE `tabid` = ' . (int) $t->tabid; if ( ! $this->_sqlUpgrader->_doQuery( $sql ) ) { $this->_sqlUpgrader->_setError( 'Failed moving core tab from old tabid: ' . $t->tabid . ' to new tabid: ' . $newTabId . ' because of error:' . $this->_db->getErrorMsg(), $sql ); break; } else { $this->_sqlUpgrader->_setLog( 'Moved core tab from old tabid: ' . $t->tabid . ' to new tabid: ' . $newTabId, $sql, 'change' ); } // b) change fields' tabid: if ( isset( $tabsFields[$t->tabid] ) && ( count( $tabsFields[$t->tabid] ) > 0 ) ) { $sql = 'UPDATE `#__comprofiler_fields` SET `tabid` = ' . (int) $newTabId . ' WHERE `tabid` = ' . (int) $t->tabid; if ( ! $this->_sqlUpgrader->_doQuery( $sql ) ) { $this->_sqlUpgrader->_setError( 'Failed changing fields from old core tabid: ' . $oldTabId . ' to new tabid: ' . $t->tabid . ' because of error:' . $this->_db->getErrorMsg(), $sql ); break; } else { $this->_sqlUpgrader->_setLog( 'Changed fields from old core tabid: ' . $oldTabId . ' to new tabid: ' . $t->tabid, $sql, 'change' ); } } } } } // now missing core tabs will be inserted in the new 1.2 upgrader in next step. return true; }
/** * Compacts the ordering sequence of the selected records * * @param string $where Additional where query to limit ordering to a particular subset of records * @param array $cids of table key ids which should preserve their position (in addition of the negative positions) * @param string $ordering name of ordering column in table * @return boolean TRUE success, FALSE failed, with error of database updated. */ function updateOrder( $where = '' , $cids = null, $ordering = 'ordering' ) { $k = $this->_tbl_key; if (!array_key_exists( $ordering, get_class_vars( strtolower(get_class( $this )) ) )) { $this->_error = "WARNING: ".strtolower(get_class( $this ))." does not support ordering field" . $ordering . "."; return false; } if ($this->_tbl == "#__content_frontpage") { $order2 = ", content_id DESC"; } else { $order2 = ""; } $this->_db->setQuery( "SELECT $this->_tbl_key, $ordering FROM $this->_tbl" . ($where ? "\nWHERE $where" : '') . "\nORDER BY " . $ordering . $order2 ); if (!($orders = $this->_db->loadObjectList())) { $this->_error = $this->_db->getErrorMsg(); return false; } $n=count( $orders ); $iOfThis = null; if($cids !== null) { $cidsOrderings = array(); // determine list of reserved/changed ordering numbers for ($i=0; $i < $n; $i++) { if (in_array($orders[$i]->$k, $cids)) { $cidsOrderings[$orders[$i]->$k] = $orders[$i]->$ordering; } } $j = 1; // change ordering numbers outside of reserved and negative ordering numbers list for ($i=0; $i < $n; $i++) { if ($orders[$i]->$k == $this->$k) { // place 'this' record in the desired location at the end ! $iOfThis = $i; if ($orders[$i]->$ordering == $j) { $j++; } } else if (in_array($orders[$i]->$k, $cids)) { if ($orders[$i]->$ordering == $j) { $j++; } } else { if ($orders[$i]->$ordering >= 0) { $orders[$i]->$ordering = $j++; } while (in_array($orders[$i]->$ordering, $cidsOrderings)) { $orders[$i]->$ordering = $j++; } } } } else { $j = 1; for ($i=0; $i < $n; $i++) { if ($orders[$i]->$k == $this->$k) { // place 'this' record in the desired location at the end ! $iOfThis = $i; if ($orders[$i]->$ordering == $j) { $j++; } } else if ($orders[$i]->$ordering != $this->$ordering && $this->$ordering > 0 && $orders[$i]->$ordering >= 0) { $orders[$i]->$ordering = $j++; } else if ($orders[$i]->$ordering == $this->$ordering && $this->$ordering > 0 && $orders[$i]->$ordering >= 0) { if ($orders[$i]->$ordering == $j) { $j++; } $orders[$i]->$ordering = $j++; } } } if ($iOfThis !== null) { $orders[$iOfThis]->$ordering = min( $this->$ordering, $j ); } // sort entries by ->$ordering: $this->_cbc_cbc_ordering_tmp = $ordering; usort($orders, array( $this, "_cmp_obj" )); unset( $this->_cbc_cbc_ordering_tmp ); // compact ordering: $j = 1; for ($i=0; $i < $n; $i++) { if ($orders[$i]->$ordering >= 0) { $orders[$i]->$ordering = $j++; } } for ($i=0; $i < $n; $i++) { if (($orders[$i]->$ordering >= 0) or ($orders[$i]->$k == $this->$k)) { $this->_db->setQuery( "UPDATE $this->_tbl" . "\nSET $ordering='".$orders[$i]->$ordering."' WHERE $k='".$orders[$i]->$k."'" ); $this->_db->query(); } } // if we didn't find to reorder the current record, make it last if (($iOfThis === null) && ($this->$ordering > 0)) { $order = $n+1; $this->_db->setQuery( "UPDATE $this->_tbl" . "\nSET $ordering='$order' WHERE $k='".$this->$k."'" ); $this->_db->query(); } return true; }