Example #1
0
 /** Function endElement */
 public function endElement($parser, $name)
 {
     $parent = $this->getParent();
     // should be before endElement
     parent::endElement($parser, $name);
     if ($this->UploadError) {
         return;
     }
     if ($name == 'FILE' && $parent == 'UPLOAD') {
         $this->UploadFile->BuildId = $this->BuildId;
         // Close base64 temporary file writing handler
         fclose($this->Base64TmpFileWriteHandle);
         unset($this->Base64TmpFileWriteHandle);
         // Decode file using 'read by chunk' approach to minimize memory footprint
         // Note: Using stream_filter_append/stream_copy_to_stream is more efficient but
         // return an "invalid byte sequence" on windows
         $rhandle = fopen($this->Base64TmpFilename, 'r');
         $whandle = fopen($this->TmpFilename, 'w+');
         $chunksize = 4096;
         while (!feof($rhandle)) {
             fwrite($whandle, base64_decode(fread($rhandle, $chunksize)));
         }
         fclose($rhandle);
         unset($rhandle);
         fclose($whandle);
         unset($whandle);
         // Delete base64 encoded file
         $success = cdash_unlink($this->Base64TmpFilename);
         if (!$success) {
             add_log("Failed to delete file '" . $this->Base64TmpFilename . "'", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_WARNING);
         }
         // Check file size against the upload quota
         $upload_file_size = filesize($this->TmpFilename);
         $Project = new Project();
         $Project->Id = $this->projectid;
         $Project->Fill();
         if ($upload_file_size > $Project->UploadQuota) {
             add_log("Size of uploaded file {$this->TmpFilename} is {$upload_file_size} bytes, which is greater " . "than the total upload quota for this project ({$Project->UploadQuota} bytes)", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_ERR);
             $this->UploadError = true;
             cdash_unlink($this->TmpFilename);
             return;
         }
         // Compute SHA1 of decoded file
         $upload_file_sha1 = sha1_file($this->TmpFilename);
         // TODO Check if a file if same buildid, sha1 and name has already been uploaded
         $this->UploadFile->Sha1Sum = $upload_file_sha1;
         $this->UploadFile->Filesize = $upload_file_size;
         // Extension of the file indicates if it's a data file that should be hosted on CDash of if
         // an URL should just be considered. File having extension ".url" are expected to contain an URL.
         $path_parts = pathinfo($this->UploadFile->Filename);
         $ext = $path_parts['extension'];
         if ($ext == "url") {
             $this->UploadFile->IsUrl = true;
             // Read content of the file
             $url_length = 255;
             // max length of 'uploadfile.filename' field
             $this->UploadFile->Filename = trim(file_get_contents($this->TmpFilename, NULL, NULL, 0, $url_length));
             cdash_unlink($this->TmpFilename);
             //add_log("this->UploadFile->Filename '".$this->UploadFile->Filename."'", __FILE__.':'.__LINE__.' - '.__FUNCTION__, LOG_INFO);
         } else {
             $this->UploadFile->IsUrl = false;
             $upload_dir = realpath($GLOBALS['CDASH_UPLOAD_DIRECTORY']);
             if (!$upload_dir) {
                 add_log("realpath cannot resolve CDASH_UPLOAD_DIRECTORY '" . $GLOBALS['CDASH_UPLOAD_DIRECTORY'] . "' with cwd '" . getcwd() . "'", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_WARNING);
             }
             $upload_dir .= '/' . $this->UploadFile->Sha1Sum;
             $uploadfilepath = $upload_dir . '/' . $this->UploadFile->Sha1Sum;
             // Check if upload directory should be created
             if (!file_exists($upload_dir)) {
                 $success = mkdir($upload_dir);
                 if (!$success) {
                     add_log("Failed to create directory '" . $upload_dir . "'", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_ERR);
                     $this->UploadError = true;
                     return;
                 }
             }
             // Check if file has already been referenced
             if (!file_exists($uploadfilepath)) {
                 $success = rename($this->TmpFilename, $uploadfilepath);
                 if (!$success) {
                     add_log("Failed to rename file '" . $this->TmpFilename . "' into '" . $uploadfilepath . "'", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_ERR);
                     $this->UploadError = true;
                     return;
                 }
             } else {
                 // Delete decoded temporary file since it has already been addressed
                 $success = cdash_unlink($this->TmpFilename);
                 if (!$success) {
                     add_log("Failed to delete file '" . $this->TmpFilename . "'", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_WARNING);
                 }
             }
             // Generate symlink name
             $symlinkName = $path_parts['basename'];
             // Check if symlink should be created
             $createSymlink = !file_exists($upload_dir . '/' . $symlinkName);
             if ($createSymlink) {
                 // Create symlink
                 if (function_exists("symlink")) {
                     $success = symlink($uploadfilepath, $upload_dir . '/' . $symlinkName);
                 } else {
                     $success = 0;
                 }
                 if (!$success) {
                     // Log actual non-testing symlink failure as an error:
                     $level = LOG_ERR;
                     // But if testing, log as info only:
                     if ($GLOBALS['CDASH_TESTING_MODE']) {
                         $level = LOG_INFO;
                     }
                     add_log("Failed to create symlink [target:'" . $uploadfilepath . "', name: '" . $upload_dir . '/' . $symlinkName . "']", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, $level);
                     // Fall back to a full copy if symlink does not exist, or if it failed:
                     $success = copy($uploadfilepath, $upload_dir . '/' . $symlinkName);
                     if (!$success) {
                         add_log("Failed to copy file (symlink fallback) [target:'" . $uploadfilepath . "', name: '" . $upload_dir . '/' . $symlinkName . "']", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_ERR);
                         $this->UploadError = true;
                         return;
                     }
                 }
             }
         }
         // Update model
         $success = $this->UploadFile->Insert();
         if (!$success) {
             add_log("UploadFile model - Failed to insert row associated with file: '" . $this->UploadFile->Filename . "'", __FILE__ . ':' . __LINE__ . ' - ' . __FUNCTION__, LOG_ERR);
         }
         $Project->CullUploadedFiles();
         // Reset UploadError so that the handler could attempt to process following files
         $this->UploadError = false;
     }
 }