protected function actionUpgrade($params)
 {
     if (!$this->isCli()) {
         echo '<pre>';
     }
     if (!version_compare(phpversion(), "5.3", ">=")) {
         exit("You are running a PHP version older than 5.3. PHP 5.3 or greater is required to run Group-Office " . \GO::config()->version);
     }
     $this->lockAction();
     GO::setIgnoreAclPermissions(true);
     GO::session()->runAsRoot();
     \GO::clearCache();
     \GO\Base\Db\Columns::$forceLoad = true;
     //don't be strict in upgrade process
     \GO::getDbConnection()->query("SET sql_mode=''");
     $v3 = $this->_checkV3();
     $logDir = new \GO\Base\Fs\Folder(\GO::config()->file_storage_path . 'log/upgrade/');
     $logDir->create();
     global $logFile;
     $logFile = $logDir->path() . '/' . date('Ymd_Gi') . '.log';
     touch($logFile);
     if (!is_writable($logFile)) {
         die('Fatal error: Could not write to log file');
     }
     ob_start("GO\\Core\\Controller\\MaintenanceController::ob_upgrade_log");
     echo "Updating " . \GO::config()->product_name . " database\n";
     //build an array of all update files. The queries are indexed by timestamp
     //so they will all be executed in the right order.
     $u = array();
     require \GO::config()->root_path . 'install/updates.php';
     //put the updates in an extra array dimension so we know to which module
     //they belong too.
     foreach ($updates as $timestamp => $updatequeries) {
         $u["{$timestamp}"]['core'] = $updatequeries;
     }
     $modules = \GO::modules()->getAllModules();
     while ($module = array_shift($modules)) {
         if ($module->isAvailable()) {
             $updatesFile = $module->path . 'install/updates.php';
             if (!file_exists($updatesFile)) {
                 $updatesFile = $module->path . 'install/updates.inc.php';
             }
             if (file_exists($updatesFile)) {
                 $updates = array();
                 require $updatesFile;
                 //put the updates in an extra array dimension so we know to which module
                 //they belong too.
                 foreach ($updates as $timestamp => $updatequeries) {
                     $u["{$timestamp}"][$module->id] = $updatequeries;
                 }
             }
         }
     }
     //sort the array by timestamp
     ksort($u);
     //
     //		var_dump($u);
     //		exit();
     $currentCoreVersion = \GO::config()->get_setting('version');
     if (!$currentCoreVersion) {
         $currentCoreVersion = 0;
     }
     $counts = array();
     foreach ($u as $timestamp => $updateQuerySet) {
         foreach ($updateQuerySet as $module => $queries) {
             //echo "Getting updates for ".$module."\n";
             if (!is_array($queries)) {
                 exit("Invalid queries in module: " . $module);
             }
             if ($module == 'core') {
                 $currentVersion = $currentCoreVersion;
             } else {
                 $currentVersion = \GO::modules()->{$module}->version;
             }
             if (!isset($counts[$module])) {
                 $counts[$module] = 0;
             }
             foreach ($queries as $query) {
                 $counts[$module]++;
                 if ($counts[$module] > $currentVersion) {
                     if (substr($query, 0, 7) == 'script:') {
                         if ($module == 'core') {
                             $updateScript = \GO::config()->root_path . 'install/updatescripts/' . substr($query, 7);
                         } else {
                             $updateScript = \GO::modules()->{$module}->path . 'install/updatescripts/' . substr($query, 7);
                         }
                         if (!file_exists($updateScript)) {
                             die($updateScript . ' not found!');
                         }
                         //if(!$quiet)
                         echo 'Running ' . $updateScript . "\n";
                         flush();
                         if (empty($params['test'])) {
                             require_once $updateScript;
                         }
                     } else {
                         echo 'Excuting query: ' . $query . "\n";
                         flush();
                         if (empty($params['test'])) {
                             try {
                                 if (!empty($query)) {
                                     \GO::getDbConnection()->query($query);
                                 }
                             } catch (PDOException $e) {
                                 //var_dump($e);
                                 echo $e->getMessage() . "\n";
                                 echo "Query: " . $query;
                                 //									if ($e->getCode() == 1091 || $e->getCode() == 1060) {
                                 //										//duplicate and drop errors. Ignore those on updates
                                 //									} else {
                                 //										die();
                                 //									}
                             }
                         }
                     }
                     if (empty($params['test'])) {
                         if ($module == 'core') {
                             \GO::config()->save_setting('version', $counts[$module]);
                         } else {
                             //echo $module.' updated to '.$counts[$module]."\n";
                             $moduleModel = \GO::modules()->{$module};
                             $moduleModel->version = $counts[$module];
                             $moduleModel->save();
                         }
                         ob_flush();
                     }
                 }
             }
         }
     }
     if (empty($params['test'])) {
         echo "Database updated to version " . \GO::config()->mtime, "\n";
         ob_flush();
         \GO::config()->save_setting('upgrade_mtime', \GO::config()->mtime);
     } else {
         echo "Ran in test mode\n";
     }
     echo "Removing cached javascripts...\n\n";
     //in some exceptions alowed deletes is still on false here.
     \GO\Base\Fs\File::setAllowDeletes(true);
     \GO::clearCache();
     //rebuild listeners
     \GO\Base\Observable::cacheListeners();
     if ($v3) {
         //			if(\GO::modules()->isInstalled('projects') && \GO::modules()->isInstalled('files')){
         //				echo "Renaming projects folder temporarily for new project paths\n";
         //				$folder = \GO\Files\Model\Folder::model()->findByPath('projects');
         //				if($folder){
         //					$folder->name='oldprojects';
         //					$folder->systemSave=true;
         //					$folder->save();
         //				}
         //			}
         //			echo "Checking database after version 3.7 upgrade.\n";
         //			$this->actionCheckDatabase($params);
         //			echo "Done\n\n";
         //			ob_flush();
         $versioningFolder = new \GO\Base\Fs\Folder(\GO::config()->file_storage_path . 'versioning');
         if ($versioningFolder->exists()) {
             $versioningFolder->rename("versioning_backup_3_7");
         }
         if (!$this->isCli()) {
             echo '</pre>';
         }
         echo "Building search cache after version 3.7 upgrade.\n";
         ob_flush();
         $this->run("buildsearchcache", $params);
         ob_flush();
         if (!$this->isCli()) {
             echo '<pre>';
         }
     }
     echo "All Done!\n";
     if (!$this->isCli() && basename($_SERVER['PHP_SELF']) != 'upgrade.php') {
         echo '</pre><br /><br />';
         echo '<a href="' . \GO::config()->host . '">' . \GO::t('cmdContinue') . '</a>';
     }
     ob_end_flush();
     \GO\Base\Db\Columns::$forceLoad = false;
     //return $response;
 }
Beispiel #2
0
 /**
  * Get all default select fields. It excludes BLOBS and TEXT fields.
  * This function is used by find.
  *
  * @param boolean $single
  * @param string $tableAlias
  * @return string
  */
 public function getDefaultFindSelectFields($single = false, $tableAlias = 't')
 {
     //when upgrading we must refresh columns
     if (Columns::$forceLoad) {
         $this->columns = Columns::getColumns($this);
     }
     if ($single) {
         return $tableAlias . '.*';
     }
     foreach ($this->columns as $name => $attr) {
         if (isset($attr['gotype']) && $attr['gotype'] != 'blob' && $attr['gotype'] != 'textarea' && $attr['gotype'] != 'html') {
             $fields[] = $name;
         }
     }
     return "`{$tableAlias}`.`" . implode('`, `' . $tableAlias . '`.`', $fields) . "`";
 }
 /**
  * Returns all custom fields for this link type
  * 
  * @param int $linkType
  * @return PDOStatement 
  */
 private function _getAllFields()
 {
     //cache is cleared when a field is saved or deleted in Field::AfterSave and afterdelete
     if (!isset(self::$cacheColumns[$this->extendsModel()])) {
         $cacheKey = $this->getCacheKey();
         if ($cached = \GO::cache()->get($cacheKey)) {
             self::$attributeLabels[$this->extendsModel()] = $cached['attributeLabels'];
             self::$cacheColumns[$this->extendsModel()] = $cached['columns'];
         } else {
             $findParams = \GO\Base\Db\FindParams::newInstance()->select('t.*')->ignoreAcl()->joinRelation('category');
             $findParams->getCriteria()->addCondition('extends_model', $this->extendsModel(), '=', 'category');
             $stmt = \GO\Customfields\Model\Field::model()->find($findParams);
             self::$cacheColumns[$this->extendsModel()] = \GO\Base\Db\Columns::getColumns($this);
             self::$attributeLabels[$this->extendsModel()] = array();
             while ($field = $stmt->fetch()) {
                 self::$attributeLabels[$this->extendsModel()][$field->columnName()] = $field->category->name . ':' . $field->name;
                 self::$cacheColumns[$this->extendsModel()][$field->columnName()]['customfield'] = $field;
                 self::$cacheColumns[$this->extendsModel()][$field->columnName()]['regex'] = $field->validation_regex;
                 self::$cacheColumns[$this->extendsModel()][$field->columnName()]['gotype'] = 'customfield';
                 self::$cacheColumns[$this->extendsModel()][$field->columnName()]['unique'] = $field->unique_values;
                 //Don't validate required on the server side because customfields tabs can be disabled.
                 //self::$cacheColumns[$this->extendsModel()][$field->columnName()]['required']=$field->required;
             }
             \GO::cache()->set($cacheKey, array('attributeLabels' => self::$attributeLabels[$this->extendsModel()], 'columns' => self::$cacheColumns[$this->extendsModel()]));
         }
     }
     $this->columns = self::$cacheColumns[$this->extendsModel()];
 }
Beispiel #4
0
 public function install()
 {
     // Install the notification cron for income contracts
     \GO\Projects2\Projects2Module::createDefaultIncomeContractNotificationCron();
     //		if(!GO::modules()->isInstalled('projects')){
     GO::getDbConnection()->query("SET sql_mode=''");
     if (!Utils::tableExists("pm_projects")) {
         parent::install();
         $defaultType = new Type();
         $defaultType->name = GO::t('default');
         $defaultType->save();
         $defaultStatus = new Status();
         $defaultStatus->name = GO::t('ongoing', 'projects2');
         $defaultStatus->show_in_tree = true;
         $defaultStatus->save();
         $noneStatus = new Status();
         $noneStatus->name = GO::t('none', 'projects2');
         $noneStatus->show_in_tree = true;
         $noneStatus->filterable = true;
         $noneStatus->save();
         $status = new Status();
         $status->name = GO::t('complete', 'projects2');
         $status->complete = true;
         $status->show_in_tree = false;
         $status->save();
         $folder = new \GO\Base\Fs\Folder(GO::config()->file_storage_path . 'projects2/template-icons');
         $folder->create();
         if (!$folder->child('folder.png')) {
             $file = new \GO\Base\Fs\File(GO::modules()->projects2->path . 'install/images/folder.png');
             $file->copy($folder);
         }
         if (!$folder->child('project.png')) {
             $file = new \GO\Base\Fs\File(GO::modules()->projects2->path . 'install/images/project.png');
             $file->copy($folder);
         }
         $template = new Template();
         $template->name = GO::t('projectsFolder', 'projects2');
         $template->default_status_id = $noneStatus->id;
         $template->default_type_id = $defaultType->id;
         $template->icon = $folder->stripFileStoragePath() . '/folder.png';
         $template->project_type = Template::PROJECT_TYPE_CONTAINER;
         $template->save();
         $template->acl->addGroup(GO::config()->group_everyone);
         $template = new Template();
         $template->name = GO::t('standardProject', 'projects2');
         $template->default_status_id = $defaultStatus->id;
         $template->default_type_id = $defaultType->id;
         $template->project_type = Template::PROJECT_TYPE_PROJECT;
         $template->fields = 'responsible_user_id,status_date,customer,budget_fees,contact,expenses';
         $template->icon = $folder->stripFileStoragePath() . '/project.png';
         $template->save();
         $template->acl->addGroup(GO::config()->group_everyone);
     } else {
         GO::setMaxExecutionTime(0);
         $oldModelTypeId = \GO\Base\Model\ModelType::model()->findByModelName("GO\\Projects\\Model\\Project");
         $modelTypeId = \GO\Base\Model\ModelType::model()->findByModelName("GO\\Projects2\\Model\\Project");
         //copy old projects module tables
         $stmt = GO::getDbConnection()->query('SHOW TABLES');
         while ($r = $stmt->fetch()) {
             $tableName = $r[0];
             if (substr($tableName, 0, 9) == 'go_links_' && !is_numeric(substr($tableName, 9, 1))) {
                 try {
                     $sql = "ALTER TABLE  `{$tableName}` ADD  `ctime` INT NOT NULL DEFAULT  '0';";
                     GO::getDbConnection()->query($sql);
                 } catch (Exception $e) {
                 }
                 $sql = "DELETE FROM `{$tableName}` WHERE model_type_id=" . intval($modelTypeId);
                 GO::debug($sql);
                 GO::getDbConnection()->query($sql);
                 $sql = "INSERT IGNORE INTO `{$tableName}` SELECT id,folder_id, model_id,'{$modelTypeId}', description, ctime FROM `{$tableName}` WHERE model_type_id={$oldModelTypeId}";
                 GO::debug($sql);
                 GO::getDbConnection()->query($sql);
             }
             if (strpos($tableName, 'pm_') !== false) {
                 //some GLOBAL2000 tables we do not want to copy
                 if (!in_array($tableName, array('pm_employees', 'pm_resources', 'pm_employment_agreements'))) {
                     $newTable = str_replace('pm_', "pr2_", $tableName);
                     $sql = "DROP TABLE IF EXISTS `{$newTable}`";
                     GO::getDbConnection()->query($sql);
                     $sql = "CREATE TABLE `{$newTable}` LIKE `{$tableName}`";
                     GO::getDbConnection()->query($sql);
                     $sql = "INSERT INTO `{$newTable}` SELECT * FROM `{$tableName}`";
                     GO::getDbConnection()->query($sql);
                 }
             }
         }
         $sql = "update pr2_projects set name = replace(name, '/','-')";
         GO::getDbConnection()->query($sql);
         //			$sql = "update pr2_projects set files_folder_id=0";
         //			GO::getDbConnection()->query($sql);
         $sql = "select version from go_modules where id='projects'";
         $stmt = GO::getDbConnection()->query($sql);
         $record = $stmt->fetch(PDO::FETCH_ASSOC);
         GO::modules()->projects2->version = $record['version'];
         GO::modules()->projects2->save();
         //			GO::modules()->projects->acl->copyPermissions(GO::modules()->projects2->acl);
         //start files
         //			$sql = "UPDATE pr2_projects SET files_folder_id=(SELECT files_folder_id FROM pm_projects WHERE pm_projects.id=pr2_projects.id);";
         //			GO::getDbConnection()->query($sql);
         $fsFolder = new GO\Base\Fs\Folder(GO::config()->file_storage_path . 'projects2');
         if ($fsFolder->exists()) {
             $fsFolder->rename('projects2-' . date('c'));
         }
         $folder = \GO\Files\Model\Folder::model()->findByPath('projects');
         $folder->name = 'projects2';
         $folder->acl_id = GO::modules()->projects2->acl_id;
         $folder->save();
         //			$sql = "UPDATE pm_projects SET files_folder_id=0;";
         //			GO::getDbConnection()->query($sql);
         $sql = "update `pr2_templates` set icon = replace(icon, 'projects/', 'projects2/');";
         GO::getDbConnection()->query($sql);
         //end files
         //upgrade database
         ob_start();
         $mc = new \GO\Core\Controller\MaintenanceController();
         $mc->run("upgrade", array(), false);
         ob_end_clean();
         //create new acl's
         //			$types = \GO\Projects\Model\Type::model()->find();
         //			foreach($types as $type){
         //				$type2 = Model\Type::model()->findByPk($type->id);
         //				$type2->setNewAcl($type->user_id);
         //				$type->acl->copyPermissions($type2->acl);
         //				$type2->save();
         //			}
         $sql = "ALTER TABLE `pr2_hours` CHANGE `income_id` `old_income_id` INT( 11 ) NULL DEFAULT NULL ;";
         GO::getDbConnection()->query($sql);
         $sql = "ALTER TABLE `pr2_hours` ADD `income_id` INT( 11 ) NULL AFTER `old_income_id` ;";
         GO::getDbConnection()->query($sql);
         $sql = "UPDATE `pr2_hours` SET old_income_id=-1*old_income_id;";
         GO::getDbConnection()->query($sql);
         if (\GO\Base\Db\Utils::tableExists("pm_employment_agreements")) {
             //GLOBAL 2000 version
             $sql = "replace into pr2_employees (user_id, external_fee, internal_fee) select employee_id, max(external_fee),max(internal_fee) from pm_employment_agreements group by employee_id";
             GO::getDbConnection()->query($sql);
             $sql = "replace into pr2_resources (user_id,project_id, external_fee, internal_fee) select user_id,project_id, external_fee, internal_fee from pm_resources";
             GO::getDbConnection()->query($sql);
             //			No longer necessary because of $updates['201310041023'] in updates.inc.php :
             //				//untested
             //				$sql = "ALTER TABLE  `pr2_hours` CHANGE  `external_value`  `external_fee` DOUBLE NOT NULL DEFAULT  '0'";
             //				GO::getDbConnection()->query($sql);
         } else {
             $sql = "insert ignore into pr2_employees (user_id, external_fee, internal_fee) select user_id, max(ext_fee_value), max(int_fee_value) from pm_hours group by user_id";
             GO::getDbConnection()->query($sql);
             $sql = "insert ignore into pr2_resources (user_id,project_id, external_fee, internal_fee) select user_id,project_id, max(ext_fee_value), max(int_fee_value) from pm_hours group by user_id, project_id";
             GO::getDbConnection()->query($sql);
         }
         $sql = "update pr2_templates set project_type=1";
         GO::getDbConnection()->query($sql);
         if (GO::modules()->customfields) {
             //				require(dirname(__FILE__).'/install/migrate/models.php');
             //				\GO\Customfields\CustomfieldsModule::replaceRecords("GO\Projects\Model\Project", "GO\Projects2\Model\Project");
             //				\GO\Customfields\CustomfieldsModule::replaceRecords("GO\Projects\Model\Hour", "GO\Projects2\Model\TimeEntry");
             //$sql = "RENAME TABLE  `cf_pm_projects` TO  `cf_pr2_projects` ";
             //GO::getDbConnection()->query($sql);
             //$sql = "RENAME TABLE  `cf_pm_hours` TO  `cf_pr2_hours` ";
             //GO::getDbConnection()->query($sql);
             $sql = "update `cf_categories` set extends_model = 'GO\\\\Projects2\\\\Model\\\\Project' where extends_model = 'GO\\\\Projects\\\\Model\\\\Project';";
             GO::getDbConnection()->query($sql);
             $sql = "update `cf_categories` set extends_model = 'GO\\\\Projects2\\\\Model\\\\Hour' where extends_model = 'GO\\\\Projects\\\\Model\\\\Hour';";
             GO::getDbConnection()->query($sql);
         }
         // Now, let's make sure that all the projects have a template.
         $folder = new Folder(GO::config()->file_storage_path . 'projects2/template-icons');
         $folder->create();
         if (!$folder->child('folder.png')) {
             $file = new File(GO::modules()->projects2->path . 'install/images/folder.png');
             $file->copy($folder);
         }
         if (!$folder->child('project.png')) {
             $file = new File(GO::modules()->projects2->path . 'install/images/project.png');
             $file->copy($folder);
         }
         if (\GO::modules()->files) {
             $fileFolder = \GO\Files\Model\Folder::model()->findByPath('projects2/template-icons', true);
             if (!$fileFolder->acl_id != \GO::modules()->projects2->acl_id) {
                 $oldIgnore = \GO::$ignoreAclPermissions;
                 \GO::$ignoreAclPermissions = true;
                 $fileFolder->acl_id = \GO::modules()->projects2->acl_id;
                 $fileFolder->save();
                 \GO::$ignoreAclPermissions = $oldIgnore;
             }
             //for icons added after install
             $fileFolder->syncFilesystem();
         }
         $normalTemplate = new Template();
         $normalTemplate->name = GO::t('normalProject', 'projects2');
         $normalTemplate->project_type = Template::PROJECT_TYPE_PROJECT;
         $normalTemplate->fields = 'responsible_user_id,status_date,customer,budget_fees,contact,expenses';
         $normalTemplate->icon = $folder->stripFileStoragePath() . '/project.png';
         $normalTemplate->save();
         GO\Base\Db\Columns::$forceLoad = true;
         $noTemplateProjectsStmt = Project::model()->find(FindParams::newInstance()->criteria(FindCriteria::newInstance()->addCondition('template_id', 0)));
         GO\Base\Db\Columns::$forceLoad = false;
         foreach ($noTemplateProjectsStmt as $noTemplateProjectModel) {
             $noTemplateProjectModel->template_id = $normalTemplate->id;
             $noTemplateProjectModel->save();
         }
         // Upgrade closed weeks
         ob_start();
         $pc = new \GO\Projects2\Controller\ProjectController();
         $pc->run("v1toV2Upgrade", array(), false);
         ob_end_clean();
     }
 }
Beispiel #5
0
 /**
  * GO caches the table schema for performance. We need to clear it 
  */
 private function _clearColumnCache()
 {
     //deleted cached column schema. See AbstractCustomFieldsRecord
     \GO\Base\Db\Columns::clearCache(\GO::getModel(\GO::getModel($this->category->extends_model)->customfieldsModel()));
     \GO::cache()->delete('customfields_' . $this->category->extends_model);
 }