コード例 #1
0
ファイル: AppVersion.php プロジェクト: xyzz/CrashFix
 /**
  * This method creates a new db record if such a version does not exist yet.
  * @param string $appversion Version string.
  * @return AppVersion On success, returns AppVersion object; otherwise Null.
  */
 public static function createIfNotExists($appversion, $project_id = null)
 {
     if ($project_id == null) {
         $project_id = Yii::app()->user->getCurProjectId();
     }
     if ($project_id == null) {
         return Null;
     }
     // Ensure that project_id is a valid project ID
     $project = Project::model()->findByPk($project_id);
     if ($project == null) {
         return Null;
     }
     // Try to find an existing version with such a name
     $criteria = new CDbCriteria();
     $criteria->compare('project_id', $project_id, false, 'AND');
     $criteria->compare('version', $appversion, false, 'AND');
     $model = AppVersion::model()->find($criteria);
     if ($model != Null) {
         return $model;
     }
     $model = new AppVersion();
     $model->project_id = $project_id;
     $model->version = $appversion;
     if (!$model->save()) {
         return Null;
     }
     return $model;
 }
コード例 #2
0
ファイル: UserController.php プロジェクト: ph7pal/mei
 /**
  * 判断软件是否有更新
  */
 public function actionCheckapp()
 {
     $appinfo = array();
     $versionInfo = AppVersion::check($this->version, $this->appPlatform);
     if ($versionInfo) {
         $appinfo = array('status' => $versionInfo['status'], 'downurl' => $versionInfo['downurl'], 'content' => $versionInfo['content']);
     } else {
         $appinfo = array('status' => '1', 'downurl' => '', 'content' => '');
     }
     $this->output($appinfo, $this->succCode);
 }
コード例 #3
0
ファイル: AppVersionTest.php プロジェクト: xyzz/CrashFix
 public function testCreateIfNotExistsNullProject()
 {
     // Login as root
     $model = new LoginForm('RegularLogin');
     $model->username = "******";
     $model->password = "******";
     $this->assertTrue($model->login());
     // Create new version - assume success
     $model = AppVersion::createIfNotExists('1.5.0.0');
     $this->assertTrue($model != Null);
     // Find the new model
     $model = AppVersion::model()->find("version='1.5.0.0'");
     $this->assertTrue($model != Null);
 }
コード例 #4
0
ファイル: CrashReport.php プロジェクト: xyzz/CrashFix
 /**
  * This method is executed before AR is saved to database.
  * @return boolean True on success.
  */
 protected function beforeSave()
 {
     if (!parent::beforeSave()) {
         return false;
     }
     // Skip the following code on update.
     if (!$this->isNewRecord) {
         return true;
     }
     // Set project name
     if (!isset($this->project_id)) {
         // Get current project.
         $curProject = Yii::app()->user->getCurProject();
         if ($curProject === Null) {
             return false;
         }
         $this->project_id = $curProject->id;
     }
     // Check if project is active or disabled. Do not allow to save
     // if project is disabled.
     $project = Project::model()->findByPk($this->project_id);
     if ($project === Null) {
         $this->addError('project_id', 'No such a project name found.');
         return false;
     }
     if ($project->status != Project::STATUS_ACTIVE) {
         $this->addError('project_id', 'This project is disabled and not accepting crash reports.');
         return false;
     }
     // Set 'appversion_id' attribute.
     $ver = AppVersion::createIfNotExists(isset($this->appversion) ? $this->appversion : '(not set)', $this->project_id);
     if ($ver === Null) {
         $this->addError('appversion', 'Invalid application version.');
         return false;
     }
     $this->appversion_id = $ver->id;
     // Set crash group ID.
     $crashGroup = $this->createCrashGroup();
     if ($crashGroup === Null) {
         return false;
     }
     $this->groupid = $crashGroup->id;
     // Check if project has quota of crash reports per group
     if ($project->crash_reports_per_group_quota > 0) {
         // Check count of crash reports in crash group and compare it with
         // quota.
         $reportCount = $crashGroup->crashReportCount;
         if ($reportCount >= $project->crash_reports_per_group_quota) {
             $this->addError('fileAttachment', 'Max crash report count per group reached.');
             return false;
         }
     }
     // Save uploaded file to its persistent location.
     if (!$this->saveFileAttachment()) {
         return false;
     }
     // Set received timestamp.
     $this->received = time();
     // Set IP address
     $this->ipaddress = Yii::app()->request->userHostAddress;
     // Set crash report status.
     $this->status = self::STATUS_PENDING_PROCESSING;
     // Success.
     return true;
 }
コード例 #5
0
ファイル: BatchImporter.php プロジェクト: xyzz/CrashFix
 /**
  * Import files for certain project.
  * @param string $dirName Directory where to look for files.
  * @param string $projName Name of the project.
  * @return true on success; otherwise false.
  */
 private function importProjectFiles($dirName, $projName, $type)
 {
     //echo 'Importing project files from dir: '.$dirName.'\n';
     // Look for such a project name
     $project = Project::model()->find('name=:name', array(':name' => $projName));
     if ($project === null) {
         Yii::log('Such a project name not found: ' . $projName, 'error');
         return false;
     }
     // Get file list in the directory
     $fileList = scandir($dirName);
     if ($fileList == false) {
         Yii::log('Directory name is invalid: ' . $dirName, 'error');
         return false;
     }
     // Walk through files
     foreach ($fileList as $index => $file) {
         if ($file != '.' && $file != '..' && is_dir($dirName . '/' . $file)) {
             $appver = AppVersion::createIfNotExists($file, $project->id);
             $subDir = $dirName . '/' . $file;
             if ($type == self::IMPORT_CRASH_REPORTS) {
                 $this->importCrashReports($subDir, $project->id, $appver->id);
             } else {
                 $this->importDebugInfo($subDir, $project->id, $appver->id);
             }
         }
     }
     // Done
     return true;
 }
コード例 #6
0
ファイル: WebUser.php プロジェクト: xyzz/CrashFix
 /**
  * Returns the list of app versions available for current project.
  * @param $selVer integer On output, receives the currently selected version ID.
  * @return array The list of versions.
  */
 public function getCurProjectVersions(&$selVer)
 {
     // Check if there is a project currently selected
     if ($this->getCurProjectId() == false) {
         // There is no project currently selected
         throw new CHttpException(403, 'Invalid request.');
     }
     // Select all versions for this project
     $criteria = new CDbCriteria();
     $criteria->condition = 'project_id=' . $this->getCurProjectId();
     $criteria->order = 'version DESC';
     $models = AppVersion::model()->findAll($criteria);
     // Prepare the list of versions.
     $versions = array();
     foreach ($models as $model) {
         $versions[$model->id] = $model->version;
     }
     if (count($versions) == 0) {
         $versions[Project::PROJ_VER_NOT_SET] = '(not set)';
     }
     $versions[Project::PROJ_VER_ALL] = '(all)';
     $user = Yii::app()->user->loadModel();
     // Check which version is current
     if ($user->cur_appversion_id != null) {
         $selVer = $user->cur_appversion_id;
         // Validate
         $found = false;
         foreach ($versions as $key => $val) {
             if ($key == $selVer) {
                 $found = true;
                 break;
             }
         }
         if (!$found) {
             // Saved version is invalid
             // Take the first version from list
             reset($versions);
             // Move array pointer to the first element
             $selVer = key($versions);
             // Save current ver
             $user->cur_appversion_id = $selVer;
             $user->save();
         }
     } else {
         // Take the first version from list
         reset($versions);
         // Move array pointer to the first element
         $selVer = key($versions);
     }
     return $versions;
 }
コード例 #7
0
ファイル: PollCommand.php プロジェクト: xyzz/CrashFix
 /**
  * This method reads crash report information from XML file and
  * updates appropriate database tables. 
  * @param string $xmlFileName XML file name.
  * @param integer $crashReportId Crash report ID in database.
  * @return boolean true on success.
  */
 public function importCrashReportFromXml($xmlFileName, $crashReportId)
 {
     $status = false;
     // Find appropriate {{crashreport}} table record
     $criteria = new CDbCriteria();
     $criteria->select = '*';
     $criteria->condition = 'id=' . $crashReportId;
     $crashReport = CrashReport::model()->find($criteria);
     if ($crashReport == Null) {
         Yii::log('Not found crash report id=' . $crashReportId);
         return $status;
     }
     $crashReport->status = CrashReport::STATUS_PROCESSED;
     // Begin DB transaction
     $transaction = Yii::app()->db->beginTransaction();
     try {
         // Load XML file
         $doc = @simplexml_load_file($xmlFileName);
         if ($doc == Null) {
             throw new Exception('CrashFix service has encountered an error when retrieving information from crash report file');
         }
         // Get command return status message from XML
         $elemSummary = $doc->Summary;
         if ($elemSummary == Null) {
             throw new Exception('Internal error: not found Summary element in XML document ' . $xmlFileName);
         }
         // Extract crash report info
         $generatorVersion = (int) $elemSummary->GeneratorVersion;
         $crashGuid = (string) $elemSummary->CrashGUID;
         $appName = (string) $elemSummary->ApplicationName;
         $appVersion = (string) $elemSummary->ApplicationVersion;
         $exeImage = (string) $elemSummary->ExecutableImage;
         $dateCreated = (string) $elemSummary->DateCreatedUTC;
         $osNameReg = (string) $elemSummary->OSNameReg;
         $osVersionMinidump = (string) $elemSummary->OSVersionMinidump;
         $osIs64Bit = (int) $elemSummary->OSIs64Bit;
         $geoLocation = (string) $elemSummary->GeographicLocation;
         $productType = (string) $elemSummary->ProductType;
         $cpuArchitecture = (string) $elemSummary->CPUArchitecture;
         $cpuCount = (int) $elemSummary->CPUCount;
         $guiResourceCount = (int) $elemSummary->GUIResourceCount;
         $openHandleCount = $elemSummary->OpenHandleCount;
         $memoryUsageKbytes = $elemSummary->MemoryUsageKbytes;
         $exceptionType = (string) $elemSummary->ExceptionType;
         $exceptionAddress = $elemSummary->ExceptionAddress;
         $sehExceptionCode = $elemSummary->SEHExceptionCode;
         $exceptionThreadID = $elemSummary->ExceptionThreadID;
         $exceptionModuleName = (string) $elemSummary->ExceptionModuleName;
         $exceptionModuleBase = (string) $elemSummary->ExceptionModuleBase;
         if (strlen($exceptionModuleBase) == 0) {
             $exceptionModuleBase = 0;
         }
         $crashReport->exceptionmodulebase = $exceptionModuleBase;
         $userEmail = (string) $elemSummary->UserEmail;
         $problemDescription = (string) $elemSummary->ProblemDescription;
         // Set crash report fields
         $crashReport->status = CrashReport::STATUS_PROCESSED;
         $crashReport->crashrptver = $generatorVersion;
         $crashReport->crashguid = $crashGuid;
         $ver = AppVersion::createIfNotExists($appVersion, $crashReport->project_id);
         $crashReport->appversion_id = $ver->id;
         if (strlen($userEmail) != 0) {
             $crashReport->emailfrom = $userEmail;
         }
         if (strlen($problemDescription) != 0) {
             $crashReport->description = $problemDescription;
         }
         if (strlen($dateCreated) != 0) {
             $crashReport->date_created = strtotime($dateCreated);
         }
         $crashReport->os_name_reg = $osNameReg;
         $crashReport->os_ver_mdmp = $osVersionMinidump;
         $crashReport->os_is_64bit = $osIs64Bit;
         $crashReport->geo_location = $geoLocation;
         $crashReport->product_type = $productType;
         $crashReport->cpu_architecture = $cpuArchitecture;
         $crashReport->cpu_count = $cpuCount;
         $crashReport->gui_resource_count = $guiResourceCount;
         $crashReport->memory_usage_kbytes = $memoryUsageKbytes;
         $crashReport->open_handle_count = $openHandleCount;
         $crashReport->exception_type = $exceptionType;
         if (strlen($sehExceptionCode) != 0) {
             $crashReport->exception_code = $sehExceptionCode;
         }
         if (strlen($exceptionThreadID) != 0) {
             $crashReport->exception_thread_id = $exceptionThreadID;
         }
         if (strlen($exceptionAddress) != 0) {
             $crashReport->exceptionaddress = $exceptionAddress;
         }
         if (strlen($exceptionModuleName) != 0) {
             $crashReport->exceptionmodule = $exceptionModuleName;
         }
         if (strlen($exceptionModuleBase) != 0) {
             $crashReport->exceptionmodulebase = $exceptionModuleBase;
         }
         $crashReport->exe_image = $exeImage;
         // Validate crash report fields
         if (!$crashReport->validate()) {
             // There are some errors
             $errors = $crashReport->getErrors();
             foreach ($errors as $fieldName => $fieldErrors) {
                 foreach ($fieldErrors as $errorMsg) {
                     // Add an error message to log
                     Yii::log('Error in crashreport data (' . $crashReport->{$fieldName} . '): ' . $errorMsg, 'error');
                     // Associate a processing error with crash report record
                     $this->addProcessingError(ProcessingError::TYPE_CRASH_REPORT_ERROR, $crashReport->id, $errorMsg . ' (' . $crashReport->{$fieldName} . ')');
                     // Clear field - this should fix the error
                     unset($crashReport->{$fieldName});
                 }
             }
             // Clear validation errors
             $crashReport->clearErrors();
         }
         // Extract file items
         $elemFileList = $doc->FileList;
         if ($elemFileList != Null) {
             $i = 0;
             foreach ($elemFileList->Row as $elemRow) {
                 $i++;
                 if ($i == 1) {
                     continue;
                 }
                 // Skip header row
                 $itemNo = $elemRow->Cell[0]['val'];
                 $itemName = $elemRow->Cell[1]['val'];
                 $itemDesc = $elemRow->Cell[2]['val'];
                 $fileItem = new FileItem();
                 $fileItem->filename = $itemName;
                 $fileItem->description = $itemDesc;
                 $fileItem->crashreport_id = $crashReportId;
                 if (!$fileItem->save()) {
                     throw new Exception('Could not save file item record');
                 }
             }
         }
         // Extract custom props
         $elemAppDefinedProps = $doc->ApplicationDefinedProperties;
         if ($elemAppDefinedProps != Null) {
             $i = 0;
             foreach ($elemAppDefinedProps->Row as $elemRow) {
                 $i++;
                 if ($i == 1) {
                     continue;
                 }
                 // Skip header row
                 $itemNo = $elemRow->Cell[0]['val'];
                 $name = $elemRow->Cell[1]['val'];
                 $val = $elemRow->Cell[2]['val'];
                 $customProp = new CustomProp();
                 $customProp->name = $name;
                 $customProp->value = $val;
                 $customProp->crashreport_id = $crashReportId;
                 if (!$customProp->save()) {
                     throw new Exception('Could not save custom property record');
                 }
             }
         }
         // Extract the list of modules
         $elemModuleList = $doc->ModuleList;
         if ($elemModuleList != Null && $elemModuleList->count() != 0) {
             $i = 0;
             foreach ($elemModuleList->Row as $elemRow) {
                 $i++;
                 if ($i == 1) {
                     continue;
                 }
                 // Skip header row
                 $itemNo = $elemRow->Cell[0]['val'];
                 $name = $elemRow->Cell[1]['val'];
                 $symLoadStatus = $elemRow->Cell[2]['val'];
                 $loadedPdbName = $elemRow->Cell[3]['val'];
                 $loadedPdbGUID = $elemRow->Cell[4]['val'];
                 $fileVersion = $elemRow->Cell[5]['val'];
                 $timeStamp = $elemRow->Cell[6]['val'];
                 $guidnAge = $elemRow->Cell[7]['val'];
                 $module = new Module();
                 $module->crashreport_id = $crashReportId;
                 $module->name = $name;
                 $module->sym_load_status = $symLoadStatus;
                 $module->file_version = $fileVersion;
                 $module->timestamp = $timeStamp;
                 $module->matching_pdb_guid = $guidnAge;
                 $debugInfo = DebugInfo::model()->findByAttributes(array('guid' => $loadedPdbGUID));
                 if ($debugInfo != null) {
                     $module->loaded_debug_info_id = $debugInfo->id;
                 }
                 if (!$module->save()) {
                     throw new Exception('Could not save module record');
                 }
             }
         }
         // Extract the list of stack traces
         foreach ($doc->StackTrace as $elemStackTrace) {
             $threadId = $elemStackTrace->ThreadID;
             $stackTraceMD5 = $elemStackTrace->StackTraceMD5;
             $thread = new Thread();
             $thread->thread_id = $threadId;
             $thread->crashreport_id = $crashReportId;
             if (strlen($stackTraceMD5) != 0) {
                 $thread->stack_trace_md5 = $stackTraceMD5;
             }
             if (!$thread->save()) {
                 throw new Exception('Could not save thread record');
             }
             $i = 0;
             foreach ($elemStackTrace->Row as $elemRow) {
                 $i++;
                 if ($i == 1) {
                     continue;
                 }
                 // Skip header row
                 $title = $elemRow->Cell[0]['val'];
                 $addrPC = $elemRow->Cell[1]['val'];
                 $moduleName = $elemRow->Cell[2]['val'];
                 $offsInModule = $elemRow->Cell[3]['val'];
                 $symName = $elemRow->Cell[4]['val'];
                 $undSymName = $elemRow->Cell[5]['val'];
                 $offsInSym = $elemRow->Cell[6]['val'];
                 $srcFile = $elemRow->Cell[7]['val'];
                 $srcLine = $elemRow->Cell[8]['val'];
                 $offsInLine = $elemRow->Cell[9]['val'];
                 $stackFrame = new StackFrame();
                 $stackFrame->thread_id = $thread->id;
                 $stackFrame->addr_pc = $addrPC;
                 if (strlen($moduleName) != 0) {
                     $module = Module::model()->findByAttributes(array('name' => $moduleName, 'crashreport_id' => $crashReportId));
                     if ($module != null) {
                         $stackFrame->module_id = $module->id;
                     }
                     $stackFrame->offs_in_module = $offsInModule;
                 }
                 if (strlen($symName) != 0) {
                     $stackFrame->symbol_name = $symName;
                 }
                 if (strlen($undSymName) != 0) {
                     $stackFrame->und_symbol_name = $undSymName;
                 }
                 if (strlen($offsInSym) != 0) {
                     $stackFrame->offs_in_symbol = $offsInSym;
                 }
                 if (strlen($srcFile) != 0) {
                     $stackFrame->src_file_name = $srcFile;
                 }
                 if (strlen($srcLine) != 0) {
                     $stackFrame->src_line = $srcLine;
                 }
                 if (strlen($offsInLine) != 0) {
                     $stackFrame->offs_in_line = $offsInLine;
                 }
                 if (!$stackFrame->save()) {
                     throw new Exception('Could not save stack frame record');
                 }
             }
         }
         // Commit transaction
         $transaction->commit();
         // Success.
         $status = true;
     } catch (Exception $e) {
         // Rollback transaction
         $transaction->rollback();
         // Add a message to log
         Yii::log($e->getMessage(), 'error');
         $crashReport->status = CrashReport::STATUS_INVALID;
         // Associate a processing error with crash report record
         $this->addProcessingError(ProcessingError::TYPE_CRASH_REPORT_ERROR, $crashReport->id, $e->getMessage());
         $status = false;
     }
     // Update crash group based on new data
     $crashGroup = $crashReport->createCrashGroup();
     if ($crashGroup == Null) {
         Yii::log('Error creating crash group', 'error');
         $status = false;
     }
     $crashReport->groupid = $crashGroup->id;
     // Update crash report
     $saved = $crashReport->save();
     if (!$saved) {
         Yii::log('Error saving AR crashReport', 'error');
         $status = false;
     }
     if (!$saved || !$crashReport->checkQuota()) {
         Yii::log('Error checking crash report quota', 'error');
         $status = false;
         // Delete crash report
         $crashReport = $crashReport = CrashReport::model()->find('id=' . $crashReport->id);
         $crashReport->delete();
     }
     // Return status
     return $status;
 }