public function actionRemoveDuplicates($params) { \GO::setMaxExecutionTime(300); \GO::setMemoryLimit(1024); $this->render('externalHeader'); $tasklist = \GO\Tasks\Model\Tasklist::model()->findByPk($params['tasklist_id']); if (!$tasklist) { throw new \GO\Base\Exception\NotFound(); } \GO\Base\Fs\File::setAllowDeletes(false); //VERY IMPORTANT: \GO\Files\Model\Folder::$deleteInDatabaseOnly = true; \GO::session()->closeWriting(); //close writing otherwise concurrent requests are blocked. $checkModels = array("GO\\Tasks\\Model\\Task" => array('name', 'start_time', 'due_time', 'rrule', 'user_id', 'tasklist_id')); foreach ($checkModels as $modelName => $checkFields) { if (empty($params['model']) || $modelName == $params['model']) { echo '<h1>' . \GO::t('removeDuplicates') . '</h1>'; $checkFieldsStr = 't.' . implode(', t.', $checkFields); $findParams = \GO\Base\Db\FindParams::newInstance()->ignoreAcl()->select('t.id, count(*) AS n, ' . $checkFieldsStr)->group($checkFields)->having('n>1'); $findParams->getCriteria()->addCondition('tasklist_id', $tasklist->id); $stmt1 = \GO::getModel($modelName)->find($findParams); echo '<table border="1">'; echo '<tr><td>ID</th><th>' . implode('</th><th>', $checkFields) . '</th></tr>'; $count = 0; while ($dupModel = $stmt1->fetch()) { $select = 't.id'; if (\GO::getModel($modelName)->hasFiles()) { $select .= ', t.files_folder_id'; } $findParams = \GO\Base\Db\FindParams::newInstance()->ignoreAcl()->select($select . ', ' . $checkFieldsStr)->order('id', 'ASC'); $findParams->getCriteria()->addCondition('tasklist_id', $tasklist->id); foreach ($checkFields as $field) { $findParams->getCriteria()->addCondition($field, $dupModel->getAttribute($field)); } $stmt = \GO::getModel($modelName)->find($findParams); $first = true; while ($model = $stmt->fetch()) { echo '<tr><td>'; if (!$first) { echo '<span style="color:red">'; } echo $model->id; if (!$first) { echo '</span>'; } echo '</th>'; foreach ($checkFields as $field) { echo '<td>' . $model->getAttribute($field, 'html') . '</td>'; } echo '</tr>'; if (!$first) { if (!empty($params['delete'])) { if ($model->hasLinks() && $model->countLinks()) { echo '<tr><td colspan="99">' . \GO::t('skippedDeleteHasLinks') . '</td></tr>'; } elseif (($filesFolder = $model->getFilesFolder(false)) && ($filesFolder->hasFileChildren() || $filesFolder->hasFolderChildren())) { echo '<tr><td colspan="99">' . \GO::t('skippedDeleteHasFiles') . '</td></tr>'; } else { $model->delete(); } } $count++; } $first = false; } } echo '</table>'; echo '<p>' . sprintf(\GO::t('foundDuplicates'), $count) . '</p>'; echo '<br /><br /><a href="' . \GO::url('tasks/tasklist/removeDuplicates', array('delete' => true, 'tasklist_id' => $tasklist->id)) . '">' . \GO::t('clickToDeleteDuplicates') . '</a>'; } } $this->render('externalFooter'); }
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; }
public function checkModelFolder(\GO\Base\Db\ActiveRecord $model, $saveModel = false, $mustExist = false) { $oldAllowDeletes = \GO\Base\Fs\File::setAllowDeletes(false); $folder = false; if ($model->files_folder_id > 0) { GO::debug('Model has files_folder_id ' . $model->files_folder_id); $folder = \GO\Files\Model\Folder::model()->findByPk($model->files_folder_id, false, true); //record has an ID but the folder is missing from the database. Attempt to create new one. $mustExist = true; } if ($folder) { GO::debug('Folder exists in database'); $model->files_folder_id = $this->_checkExistingModelFolder($model, $folder, $mustExist); if ($saveModel && $model->isModified()) { $model->save(true); } } elseif (isset($model->acl_id) && !$model->aclOverwrite() || $mustExist) { GO::debug('Folder does not exist in database. Will create it.'); //this model has an acl_id. So we should create a shared folder with this acl. //this folder should always exist. //only new models that have it's own acl field should always have a folder. //otherwise it will be created when first accessed. $model->files_folder_id = $this->_createNewModelFolder($model); if ($saveModel && $model->isModified()) { $model->save(true); } } if (empty($model->files_folder_id)) { $model->files_folder_id = 0; } \GO\Base\Fs\File::setAllowDeletes($oldAllowDeletes); $this->fireEvent('checkmodelfolder', array($model, $folder)); return $model->files_folder_id; }