示例#1
0
	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;
	}