3 final class PhabricatorExportEngine
13 public function setViewer(PhabricatorUser
$viewer) {
14 $this->viewer
= $viewer;
18 public function getViewer() {
22 public function setSearchEngine(
23 PhabricatorApplicationSearchEngine
$search_engine) {
24 $this->searchEngine
= $search_engine;
28 public function getSearchEngine() {
29 return $this->searchEngine
;
32 public function setSavedQuery(PhabricatorSavedQuery
$saved_query) {
33 $this->savedQuery
= $saved_query;
37 public function getSavedQuery() {
38 return $this->savedQuery
;
41 public function setExportFormat(
42 PhabricatorExportFormat
$export_format) {
43 $this->exportFormat
= $export_format;
47 public function getExportFormat() {
48 return $this->exportFormat
;
51 public function setFilename($filename) {
52 $this->filename
= $filename;
56 public function getFilename() {
57 return $this->filename
;
60 public function setTitle($title) {
61 $this->title
= $title;
65 public function getTitle() {
69 public function newBulkJob(AphrontRequest
$request) {
70 $viewer = $this->getViewer();
71 $engine = $this->getSearchEngine();
72 $saved_query = $this->getSavedQuery();
73 $format = $this->getExportFormat();
76 'engineClass' => get_class($engine),
77 'queryKey' => $saved_query->getQueryKey(),
78 'formatKey' => $format->getExportFormatKey(),
79 'title' => $this->getTitle(),
80 'filename' => $this->getFilename(),
83 $job = PhabricatorWorkerBulkJob
::initializeNewJob(
85 new PhabricatorExportEngineBulkJobType(),
88 // We queue these jobs directly into STATUS_WAITING without requiring
89 // a confirmation from the user.
93 $xactions[] = id(new PhabricatorWorkerBulkJobTransaction())
94 ->setTransactionType(PhabricatorWorkerBulkJobTransaction
::TYPE_STATUS
)
95 ->setNewValue(PhabricatorWorkerBulkJob
::STATUS_WAITING
);
97 $editor = id(new PhabricatorWorkerBulkJobEditor())
99 ->setContentSourceFromRequest($request)
100 ->setContinueOnMissingFields(true)
101 ->applyTransactions($job, $xactions);
106 public function exportFile() {
107 $viewer = $this->getViewer();
108 $engine = $this->getSearchEngine();
109 $saved_query = $this->getSavedQuery();
110 $format = $this->getExportFormat();
111 $title = $this->getTitle();
112 $filename = $this->getFilename();
114 $query = $engine->buildQueryFromSavedQuery($saved_query);
116 $extension = $format->getFileExtension();
117 $mime_type = $format->getMIMEContentType();
118 $filename = $filename.'.'.$extension;
120 $format = id(clone $format)
124 $field_list = $engine->newExportFieldList();
125 $field_list = mpull($field_list, null, 'getKey');
126 $format->addHeaders($field_list);
128 // Iterate over the query results in large pages so we don't have to hold
129 // too much stuff in memory.
133 $pager = $engine->newPagerForSavedQuery($saved_query);
134 $pager->setPageSize($page_size);
136 if ($page_cursor !== null) {
137 $pager->setAfterID($page_cursor);
140 $objects = $engine->executeQuery($query, $pager);
141 $objects = array_values($objects);
142 $page_cursor = $pager->getNextPageID();
144 $export_data = $engine->newExport($objects);
145 for ($ii = 0; $ii < count($objects); $ii++
) {
146 $format->addObject($objects[$ii], $field_list, $export_data[$ii]);
148 } while ($pager->getHasMoreResults());
150 $export_result = $format->newFileData();
152 // We have all the data in one big string and aren't actually
153 // streaming it, but pretending that we are allows us to actviate
154 // the chunk engine and store large files.
155 $iterator = new ArrayIterator(array($export_result));
157 $source = id(new PhabricatorIteratorFileUploadSource())
159 ->setViewPolicy(PhabricatorPolicies
::POLICY_NOONE
)
160 ->setMIMEType($mime_type)
161 ->setRelativeTTL(phutil_units('60 minutes in seconds'))
162 ->setAuthorPHID($viewer->getPHID())
163 ->setIterator($iterator);
165 return $source->uploadFile();