Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/infrastructure/export/engine/PhabricatorExportEngine.php
12242 views
1
<?php
2
3
final class PhabricatorExportEngine
4
extends Phobject {
5
6
private $viewer;
7
private $searchEngine;
8
private $savedQuery;
9
private $exportFormat;
10
private $filename;
11
private $title;
12
13
public function setViewer(PhabricatorUser $viewer) {
14
$this->viewer = $viewer;
15
return $this;
16
}
17
18
public function getViewer() {
19
return $this->viewer;
20
}
21
22
public function setSearchEngine(
23
PhabricatorApplicationSearchEngine $search_engine) {
24
$this->searchEngine = $search_engine;
25
return $this;
26
}
27
28
public function getSearchEngine() {
29
return $this->searchEngine;
30
}
31
32
public function setSavedQuery(PhabricatorSavedQuery $saved_query) {
33
$this->savedQuery = $saved_query;
34
return $this;
35
}
36
37
public function getSavedQuery() {
38
return $this->savedQuery;
39
}
40
41
public function setExportFormat(
42
PhabricatorExportFormat $export_format) {
43
$this->exportFormat = $export_format;
44
return $this;
45
}
46
47
public function getExportFormat() {
48
return $this->exportFormat;
49
}
50
51
public function setFilename($filename) {
52
$this->filename = $filename;
53
return $this;
54
}
55
56
public function getFilename() {
57
return $this->filename;
58
}
59
60
public function setTitle($title) {
61
$this->title = $title;
62
return $this;
63
}
64
65
public function getTitle() {
66
return $this->title;
67
}
68
69
public function newBulkJob(AphrontRequest $request) {
70
$viewer = $this->getViewer();
71
$engine = $this->getSearchEngine();
72
$saved_query = $this->getSavedQuery();
73
$format = $this->getExportFormat();
74
75
$params = array(
76
'engineClass' => get_class($engine),
77
'queryKey' => $saved_query->getQueryKey(),
78
'formatKey' => $format->getExportFormatKey(),
79
'title' => $this->getTitle(),
80
'filename' => $this->getFilename(),
81
);
82
83
$job = PhabricatorWorkerBulkJob::initializeNewJob(
84
$viewer,
85
new PhabricatorExportEngineBulkJobType(),
86
$params);
87
88
// We queue these jobs directly into STATUS_WAITING without requiring
89
// a confirmation from the user.
90
91
$xactions = array();
92
93
$xactions[] = id(new PhabricatorWorkerBulkJobTransaction())
94
->setTransactionType(PhabricatorWorkerBulkJobTransaction::TYPE_STATUS)
95
->setNewValue(PhabricatorWorkerBulkJob::STATUS_WAITING);
96
97
$editor = id(new PhabricatorWorkerBulkJobEditor())
98
->setActor($viewer)
99
->setContentSourceFromRequest($request)
100
->setContinueOnMissingFields(true)
101
->applyTransactions($job, $xactions);
102
103
return $job;
104
}
105
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();
113
114
$query = $engine->buildQueryFromSavedQuery($saved_query);
115
116
$extension = $format->getFileExtension();
117
$mime_type = $format->getMIMEContentType();
118
$filename = $filename.'.'.$extension;
119
120
$format = id(clone $format)
121
->setViewer($viewer)
122
->setTitle($title);
123
124
$field_list = $engine->newExportFieldList();
125
$field_list = mpull($field_list, null, 'getKey');
126
$format->addHeaders($field_list);
127
128
// Iterate over the query results in large pages so we don't have to hold
129
// too much stuff in memory.
130
$page_size = 1000;
131
$page_cursor = null;
132
do {
133
$pager = $engine->newPagerForSavedQuery($saved_query);
134
$pager->setPageSize($page_size);
135
136
if ($page_cursor !== null) {
137
$pager->setAfterID($page_cursor);
138
}
139
140
$objects = $engine->executeQuery($query, $pager);
141
$objects = array_values($objects);
142
$page_cursor = $pager->getNextPageID();
143
144
$export_data = $engine->newExport($objects);
145
for ($ii = 0; $ii < count($objects); $ii++) {
146
$format->addObject($objects[$ii], $field_list, $export_data[$ii]);
147
}
148
} while ($pager->getHasMoreResults());
149
150
$export_result = $format->newFileData();
151
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));
156
157
$source = id(new PhabricatorIteratorFileUploadSource())
158
->setName($filename)
159
->setViewPolicy(PhabricatorPolicies::POLICY_NOONE)
160
->setMIMEType($mime_type)
161
->setRelativeTTL(phutil_units('60 minutes in seconds'))
162
->setAuthorPHID($viewer->getPHID())
163
->setIterator($iterator);
164
165
return $source->uploadFile();
166
}
167
168
}
169
170