Open Journal Systems  3.3.0
IssueQueryBuilder.inc.php
1 <?php
2 
17 
18 use Illuminate\Database\Capsule\Manager as Capsule;
20 
22 
24  protected $contextId = null;
25 
27  protected $columns = array();
28 
30  protected $orderColumn = 'i.date_published';
31 
33  protected $orderDirection = 'DESC';
34 
36  protected $isPublished = null;
37 
39  protected $issueIds = [];
40 
42  protected $volumes = null;
43 
45  protected $numbers = null;
46 
48  protected $years = null;
49 
51  protected $countOnly = null;
52 
54  protected $limit = null;
55 
57  protected $offset = 0;
58 
60  protected $searchPhrase = '';
61 
69  public function filterByContext($contextId) {
70  $this->contextId = $contextId;
71  return $this;
72  }
73 
82  public function orderBy($column, $direction = 'DESC') {
83  if ($column === 'lastModified') {
84  $this->orderColumn = 'i.last_modified';
85  } elseif ($column === 'seq') {
86  $this->orderColumn = 'o.seq';
87  } else {
88  $this->orderColumn = 'i.date_published';
89  }
90  $this->orderDirection = $direction;
91  return $this;
92  }
93 
101  public function filterByPublished($isPublished) {
102  $this->isPublished = $isPublished;
103  return $this;
104  }
105 
113  public function filterByVolumes($volumes) {
114  if (!is_null($volumes) && !is_array($volumes)) {
115  $volumes = array($volumes);
116  }
117  $this->volumes = $volumes;
118  return $this;
119  }
120 
128  public function filterByNumbers($numbers) {
129  if (!is_null($numbers) && !is_array($numbers)) {
130  $numbers = array($numbers);
131  }
132  $this->numbers = $numbers;
133  return $this;
134  }
135 
143  public function filterByYears($years) {
144  if (!is_null($years) && !is_array($years)) {
145  $years = array($years);
146  }
147  $this->years = $years;
148  return $this;
149  }
150 
158  public function filterByIds($issueIds) {
159  $this->issueIds = $issueIds;
160  return $this;
161  }
162 
170  public function searchPhrase($phrase) {
171  $this->searchPhrase = $phrase;
172  return $this;
173  }
174 
182  public function limitTo($count) {
183  $this->limit = $count;
184  return $this;
185  }
186 
194  public function offsetBy($offset) {
195  $this->offset = $offset;
196  return $this;
197  }
198 
202  public function getCount() {
203  return $this
204  ->getQuery()
205  ->select('i.issue_id')
206  ->get()
207  ->count();
208  }
209 
213  public function getIds() {
214  return $this
215  ->getQuery()
216  ->select('i.issue_id')
217  ->pluck('i.issue_id')
218  ->toArray();
219  }
220 
224  public function getQuery() {
225  $this->columns[] = 'i.*';
226  $q = Capsule::table('issues as i')
227  ->leftJoin('issue_settings as is', 'i.issue_id', '=', 'is.issue_id')
228  ->leftJoin('custom_issue_orders as o', 'o.issue_id', '=', 'i.issue_id')
229  ->orderBy($this->orderColumn, $this->orderDirection)
230  ->groupBy('i.issue_id', $this->orderColumn);
231 
232  // context
233  // Never permit a query without a context_id clause unless the '*' wildcard
234  // has been set explicitely.
235  if (is_null($this->contextId)) {
236  $q->where('i.journal_id', '=', CONTEXT_ID_NONE);
237  } elseif ($this->contextId !== '*') {
238  $q->where('i.journal_id', '=' , $this->contextId);
239  }
240 
241  // published
242  if (!is_null($this->isPublished)) {
243  $q->where('i.published', $this->isPublished ? 1 : 0);
244  }
245 
246  // volumes
247  if (!is_null($this->volumes)) {
248  $q->whereIn('i.volume', $this->volumes);
249  }
250 
251  // numbers
252  if (!is_null($this->numbers)) {
253  $q->whereIn('i.number', $this->numbers);
254  }
255 
256  // years
257  if (!is_null($this->years)) {
258  $q->whereIn('i.year', $this->years);
259  }
260 
261  // issue ids
262  if (!empty($this->issueIds)) {
263  $q->whereIn('i.issue_id', $this->issueIds);
264  }
265 
266  // search phrase
267  if (!empty($this->searchPhrase)) {
269 
270  // Add support for searching for the volume, number and year
271  // using the localized issue identification formats. In
272  // en_US this will match Vol. 1. No. 1 (2018) against:
273  // i.volume = 1 AND i.number = 1 AND i.year = 2018
274  $volume = '';
275  $number = '';
276  $year = '';
277  $volumeRegex = '/' . preg_quote(__('issue.vol')) . '\s\S/';
278  preg_match($volumeRegex, $searchPhrase, $matches);
279  if (count($matches)) {
280  $volume = trim(str_replace(__('issue.vol'), '', $matches[0]));
281  $searchPhrase = str_replace($matches[0], '', $searchPhrase);
282  }
283  $numberRegex = '/' . preg_quote(__('issue.no')) . '\s\S/';
284  preg_match($numberRegex, $searchPhrase, $matches);
285  if (count($matches)) {
286  $number = trim(str_replace(__('issue.no'), '', $matches[0]));
287  $searchPhrase = str_replace($matches[0], '', $searchPhrase);
288  }
289  preg_match('/\(\d{4}\)\:?/', $searchPhrase, $matches);
290  if (count($matches)) {
291  $year = substr($matches[0], 1, 4);
292  $searchPhrase = str_replace($matches[0], '', $searchPhrase);
293  }
294  if ($volume !== '' || $number !== '' || $year !== '') {
295  $q->where(function($q) use ($volume, $number, $year) {
296  if ($volume) {
297  $q->where('i.volume', '=', $volume);
298  }
299  if ($number) {
300  $q->where('i.number', '=', $number);
301  }
302  if ($year) {
303  $q->where('i.year', '=', $year);
304  }
305  });
306  }
307 
308  $words = array_unique(explode(' ', $searchPhrase));
309  if (count($words)) {
310  foreach ($words as $word) {
311  $word = strtolower(addcslashes($word, '%_'));
312  $q->where(function($q) use ($word) {
313  $q->where(function($q) use ($word) {
314  $q->where('is.setting_name', 'title');
315  $q->where(Capsule::raw('lower(is.setting_value)'), 'LIKE', "%{$word}%");
316  })
317  ->orWhere(function($q) use ($word) {
318  $q->where('is.setting_name', 'description');
319  $q->where(Capsule::raw('lower(is.setting_value)'), 'LIKE', "%{$word}%");
320  });
321 
322  // Match any four-digit number to the year
323  if (ctype_digit($word) && strlen($word) === 4) {
324  $q->orWhere('i.year', '=', $word);
325  }
326  });
327  }
328  }
329  }
330 
331  // Allow third-party query statements
332  \HookRegistry::call('Issue::getMany::queryObject', array(&$q, $this));
333 
334  $q->select($this->columns);
335 
336  return $q;
337  }
338 }
APP\Services\QueryBuilders\IssueQueryBuilder\$years
$years
Definition: IssueQueryBuilder.inc.php:75
APP\Services\QueryBuilders\IssueQueryBuilder\filterByContext
filterByContext($contextId)
Definition: IssueQueryBuilder.inc.php:108
APP\Services\QueryBuilders\IssueQueryBuilder\filterByIds
filterByIds($issueIds)
Definition: IssueQueryBuilder.inc.php:197
APP\Services\QueryBuilders\IssueQueryBuilder\getCount
getCount()
Definition: IssueQueryBuilder.inc.php:241
APP\Services\QueryBuilders\IssueQueryBuilder\filterByVolumes
filterByVolumes($volumes)
Definition: IssueQueryBuilder.inc.php:152
APP\Services\QueryBuilders\IssueQueryBuilder\$orderDirection
$orderDirection
Definition: IssueQueryBuilder.inc.php:45
APP\Services\QueryBuilders\IssueQueryBuilder\$searchPhrase
$searchPhrase
Definition: IssueQueryBuilder.inc.php:99
APP\Services\QueryBuilders\IssueQueryBuilder\$issueIds
$issueIds
Definition: IssueQueryBuilder.inc.php:57
APP\Services\QueryBuilders\IssueQueryBuilder\getQuery
getQuery()
Definition: IssueQueryBuilder.inc.php:263
APP\Services\QueryBuilders\IssueQueryBuilder
Definition: IssueQueryBuilder.inc.php:21
APP\Services\QueryBuilders\IssueQueryBuilder\offsetBy
offsetBy($offset)
Definition: IssueQueryBuilder.inc.php:233
APP\Services\QueryBuilders\IssueQueryBuilder\filterByNumbers
filterByNumbers($numbers)
Definition: IssueQueryBuilder.inc.php:167
APP\Services\QueryBuilders\IssueQueryBuilder\getIds
getIds()
Definition: IssueQueryBuilder.inc.php:252
APP\Services\QueryBuilders\IssueQueryBuilder\filterByYears
filterByYears($years)
Definition: IssueQueryBuilder.inc.php:182
APP\Services\QueryBuilders\IssueQueryBuilder\$limit
$limit
Definition: IssueQueryBuilder.inc.php:87
APP\Services\QueryBuilders\IssueQueryBuilder\searchPhrase
searchPhrase($phrase)
Definition: IssueQueryBuilder.inc.php:209
APP\Services\QueryBuilders\IssueQueryBuilder\filterByPublished
filterByPublished($isPublished)
Definition: IssueQueryBuilder.inc.php:140
Seboettg\Collection\count
count()
Definition: ArrayListTrait.php:253
APP\Services\QueryBuilders\IssueQueryBuilder\$contextId
$contextId
Definition: IssueQueryBuilder.inc.php:27
APP\Services\QueryBuilders\IssueQueryBuilder\$isPublished
$isPublished
Definition: IssueQueryBuilder.inc.php:51
APP\Services\QueryBuilders\IssueQueryBuilder\$offset
$offset
Definition: IssueQueryBuilder.inc.php:93
APP\Services\QueryBuilders\IssueQueryBuilder\$volumes
$volumes
Definition: IssueQueryBuilder.inc.php:63
APP\Services\QueryBuilders
Definition: ContextQueryBuilder.inc.php:14
APP\Services\QueryBuilders\IssueQueryBuilder\limitTo
limitTo($count)
Definition: IssueQueryBuilder.inc.php:221
APP\Services\QueryBuilders\IssueQueryBuilder\orderBy
orderBy($column, $direction='DESC')
Definition: IssueQueryBuilder.inc.php:121
APP\Services\QueryBuilders\IssueQueryBuilder\$orderColumn
$orderColumn
Definition: IssueQueryBuilder.inc.php:39
APP\Services\QueryBuilders\IssueQueryBuilder\$columns
$columns
Definition: IssueQueryBuilder.inc.php:33
APP\Services\QueryBuilders\IssueQueryBuilder\$countOnly
$countOnly
Definition: IssueQueryBuilder.inc.php:81
HookRegistry\call
static call($hookName, $args=null)
Definition: HookRegistry.inc.php:86
PKP\Services\QueryBuilders\Interfaces\EntityQueryBuilderInterface
Definition: EntityQueryBuilderInterface.inc.php:19
APP\Services\QueryBuilders\IssueQueryBuilder\$numbers
$numbers
Definition: IssueQueryBuilder.inc.php:69