Open Journal Systems  2.4.4
 All Classes Namespaces Functions Variables Groups Pages
FilterDAO.inc.php
1 <?php
2 
42 import('lib.pkp.classes.filter.Filter');
43 
44 class FilterDAO extends DAO {
46  var $additionalFieldNames;
47 
49  var $localeFieldNames;
50 
54  function FilterDAO() {
55  parent::DAO();
56  }
57 
72  function &configureObject($filterClassName, $filterGroupSymbolic, $settings = array(), $asTemplate = false, $contextId = 0, $subFilters = array(), $persist = true) {
73  $falseVar = false;
74 
75  // Retrieve the filter group from the database.
76  $filterGroupDao =& DAORegistry::getDAO('FilterGroupDAO'); /* @var $filterGroupDao FilterGroupDAO */
77  $filterGroup =& $filterGroupDao->getObjectBySymbolic($filterGroupSymbolic);
78  if (!is_a($filterGroup, 'FilterGroup')) return $falseVar;
79 
80  // Instantiate the filter.
81  $filter =& instantiate($filterClassName, 'PersistableFilter', null, 'execute', $filterGroup); /* @var $filter PersistableFilter */
82  if (!is_object($filter)) return $falseVar;
83 
84  // Is this a template?
85  $filter->setIsTemplate((boolean)$asTemplate);
86 
87  // Add sub-filters (if any).
88  if (!empty($subFilters)) {
89  assert(is_a($filter, 'CompositeFilter'));
90  assert(is_array($subFilters));
91  foreach($subFilters as $subFilter) {
92  $filter->addFilter($subFilter);
93  unset($subFilter);
94  }
95  }
96 
97  // Parameterize the filter.
98  assert(is_array($settings));
99  foreach($settings as $key => $value) {
100  $filter->setData($key, $value);
101  }
102 
103  // Persist the filter.
104  if ($persist) {
105  $filterId = $this->insertObject($filter, $contextId);
106  if (!is_integer($filterId) || $filterId == 0) return $falseVar;
107  }
108 
109  return $filter;
110  }
111 
119  function insertObject(&$filter, $contextId = CONTEXT_ID_NONE) {
120  $filterGroup =& $filter->getFilterGroup();
121  assert($filterGroup->getSymbolic() != FILTER_GROUP_TEMPORARY_ONLY);
122 
123  $this->update(
124  sprintf('INSERT INTO filters
125  (filter_group_id, context_id, display_name, class_name, is_template, parent_filter_id, seq)
126  VALUES (?, ?, ?, ?, ?, ?, ?)'),
127  array(
128  (int) $filterGroup->getId(),
129  (int) $contextId,
130  $filter->getDisplayName(),
131  $filter->getClassName(),
132  $filter->getIsTemplate()?1:0,
133  (int) $filter->getParentFilterId(),
134  (int) $filter->getSeq()
135  )
136  );
137  $filter->setId((int)$this->getInsertId());
139  'filter_settings', $filter,
140  array('filter_id' => $filter->getId())
141  );
142 
143  // Recursively insert sub-filters.
144  $this->_insertSubFilters($filter);
145 
146  return $filter->getId();
147  }
148 
154  function &getObject(&$filter) {
155  return $this->getObjectById($filter->getId());
156  }
157 
164  function &getObjectById($filterId, $allowSubfilter = false) {
165  $result =& $this->retrieve(
166  'SELECT * FROM filters
167  WHERE '.($allowSubfilter ? '' : 'parent_filter_id = 0 AND '). '
168  filter_id = ?',
169  (int) $filterId
170  );
171 
172  $filter = null;
173  if ($result->RecordCount() != 0) {
174  $filter =& $this->_fromRow($result->GetRowAssoc(false));
175  }
176 
177  $result->Close();
178  unset($result);
179 
180  return $filter;
181  }
182 
193  function &getObjectsByClass($className, $contextId = CONTEXT_ID_NONE, $getTemplates = false, $allowSubfilters = false) {
194  $result =& $this->retrieve(
195  'SELECT * FROM filters
196  WHERE context_id = ? AND
197  class_name = ? AND
198  ' . ($allowSubfilters ? '' : ' parent_filter_id = 0 AND ') . '
199  ' . ($getTemplates ? ' is_template = 1' : ' is_template = 0'),
200  array((int) $contextId, $className)
201  );
202 
203  $daoResultFactory = new DAOResultFactory($result, $this, '_fromRow', array('filter_id'));
204  return $daoResultFactory;
205  }
206 
219  function &getObjectsByGroupAndClass($groupSymbolic, $className, $contextId = CONTEXT_ID_NONE, $getTemplates = false, $allowSubfilters = false) {
220  $result =& $this->retrieve(
221  'SELECT f.* FROM filters f'.
222  ' INNER JOIN filter_groups fg ON f.filter_group_id = fg.filter_group_id'.
223  ' WHERE fg.symbolic = ? AND f.context_id = ? AND f.class_name = ?'.
224  ' '.($allowSubfilters ? '' : 'AND f.parent_filter_id = 0').
225  ' AND '.($getTemplates ? 'f.is_template = 1' : 'f.is_template = 0'),
226  array($groupSymbolic, (int) $contextId, $className)
227  );
228 
229  $daoResultFactory = new DAOResultFactory($result, $this, '_fromRow', array('filter_id'));
230  return $daoResultFactory;
231  }
232 
245  function &getObjectsByTypeDescription($inputTypeDescription, $outputTypeDescription, $data = null, $dataIsInput = true) {
246  static $filterCache = array();
247  static $objectFilterCache = array();
248 
249  // We do not yet support array data types. Implement when required.
250  assert(!is_array($data));
251 
252  // Build the adapter cache.
253  $filterCacheKey = md5($inputTypeDescription.'=>'.$outputTypeDescription);
254  if (!isset($filterCache[$filterCacheKey])) {
255  // Get all adapter filters.
256  $result =& $this->retrieve(
257  'SELECT f.*'.
258  ' FROM filters f'.
259  ' INNER JOIN filter_groups fg ON f.filter_group_id = fg.filter_group_id'.
260  ' WHERE fg.input_type like ?'.
261  ' AND fg.output_type like ?'.
262  ' AND f.parent_filter_id = 0 AND f.is_template = 0',
263  array($inputTypeDescription, $outputTypeDescription)
264  );
265 
266  // Instantiate all filters.
267  $filterFactory = new DAOResultFactory($result, $this, '_fromRow', array('filter_id'));
268  $filterCache[$filterCacheKey] =& $filterFactory->toAssociativeArray();
269  }
270 
271  // Return all filter candidates if no data is given to check against.
272  if (is_null($data)) return $filterCache[$filterCacheKey];
273 
274  // Build the object-specific adapter cache.
275  $objectFilterCacheKey = md5($filterCacheKey.(is_object($data)?get_class($data):"'$data'").($dataIsInput?'in':'out'));
276  if (!isset($objectFilterCache[$objectFilterCacheKey])) {
277  $objectFilterCache[$objectFilterCacheKey] = array();
278  foreach($filterCache[$filterCacheKey] as $filterCandidateId => $filterCandidate) { /* @var $filterCandidate PersistableFilter */
279  // Check whether the given object can be transformed
280  // with this filter.
281  if ($dataIsInput) {
282  $filterDataType =& $filterCandidate->getInputType();
283  } else {
284  $filterDataType =& $filterCandidate->getOutputType();
285  }
286  if ($filterDataType->checkType($data)) $objectFilterCache[$objectFilterCacheKey][$filterCandidateId] =& $filterCandidate;
287  unset($filterCandidate);
288  }
289  }
290 
291  return $objectFilterCache[$objectFilterCacheKey];
292  }
293 
310  function &getObjectsByGroup($groupSymbolic, $contextId = CONTEXT_ID_NONE, $getTemplates = false, $checkRuntimeEnvironment = true) {
311  // 1) Get all available transformations in the group.
312  $result =& $this->retrieve(
313  'SELECT f.* FROM filters f'.
314  ' INNER JOIN filter_groups fg ON f.filter_group_id = fg.filter_group_id'.
315  ' WHERE fg.symbolic = ? AND '.($getTemplates ? 'f.is_template = 1' : 'f.is_template = 0').
316  ' '.(is_null($contextId) ? '' : 'AND f.context_id in (0, '.(int)$contextId.')').
317  ' AND f.parent_filter_id = 0',
318  $groupSymbolic
319  );
320 
321 
322  // 2) Instantiate and return all transformations in the
323  // result set that comply with the current runtime
324  // environment.
325  $matchingFilters = array();
326  foreach($result->GetAssoc() as $filterRow) {
327  $filterInstance =& $this->_fromRow($filterRow);
328  if (!$checkRuntimeEnvironment || $filterInstance->isCompatibleWithRuntimeEnvironment()) {
329  $matchingFilters[$filterInstance->getId()] =& $filterInstance;
330  }
331  unset($filterInstance);
332  }
333 
334  return $matchingFilters;
335  }
336 
341  function updateObject(&$filter) {
342  $filterGroup =& $filter->getFilterGroup();
343  assert($filterGroup->getSymbolic() != FILTER_GROUP_TEMPORARY_ONLY);
344 
345  $returner = $this->update(
346  'UPDATE filters
347  SET filter_group_id = ?,
348  display_name = ?,
349  class_name = ?,
350  is_template = ?,
351  parent_filter_id = ?,
352  seq = ?
353  WHERE filter_id = ?',
354  array(
355  (int) $filterGroup->getId(),
356  $filter->getDisplayName(),
357  $filter->getClassName(),
358  $filter->getIsTemplate()?1:0,
359  (int) $filter->getParentFilterId(),
360  (int) $filter->getSeq(),
361  (int) $filter->getId()
362  )
363  );
365  'filter_settings', $filter,
366  array('filter_id' => $filter->getId())
367  );
368 
369  // Do we update a composite filter?
370  if (is_a($filter, 'CompositeFilter')) {
371  // Delete all sub-filters
372  $this->_deleteSubFiltersByParentFilterId($filter->getId());
373 
374  // Re-insert sub-filters
375  $this->_insertSubFilters($filter);
376  }
377  }
378 
384  function deleteObject(&$filter) {
385  return $this->deleteObjectById($filter->getId());
386  }
387 
393  function deleteObjectById($filterId) {
394  $filterId = (int)$filterId;
395  $this->update('DELETE FROM filters WHERE filter_id = ?', (int) $filterId);
396  $this->update('DELETE FROM filter_settings WHERE filter_id = ?', (int) $filterId);
397  $this->_deleteSubFiltersByParentFilterId($filterId);
398  return true;
399  }
400 
401 
402  //
403  // Overridden methods from DAO
404  //
408  function updateDataObjectSettings($tableName, &$dataObject, $idArray) {
409  // Make sure that the update function finds the filter settings
410  $this->additionalFieldNames = $dataObject->getSettingNames();
411  $this->localeFieldNames = $dataObject->getLocalizedSettingNames();
412 
413  // Add runtime settings
414  foreach($dataObject->supportedRuntimeEnvironmentSettings() as $runtimeSetting => $defaultValue) {
415  if ($dataObject->hasData($runtimeSetting)) $this->additionalFieldNames[] = $runtimeSetting;
416  }
417 
418  // Update the filter settings
419  parent::updateDataObjectSettings($tableName, $dataObject, $idArray);
420 
421  // Reset the internal fields
422  unset($this->additionalFieldNames, $this->localeFieldNames);
423  }
424 
425 
426  //
427  // Implement template methods from DAO
428  //
433  assert(is_array($this->additionalFieldNames));
434  return $this->additionalFieldNames;
435  }
436 
440  function getLocaleFieldNames() {
441  assert(is_array($this->localeFieldNames));
442  return $this->localeFieldNames;
443  }
444 
445 
446  //
447  // Protected helper methods
448  //
453  function getInsertId() {
454  return parent::getInsertId('filters', 'filter_id');
455  }
456 
457 
458  //
459  // Private helper methods
460  //
467  function &_newDataObject($filterClassName, $filterGroupId) {
468  // Instantiate the filter group.
469  $filterGroupDao =& DAORegistry::getDAO('FilterGroupDAO'); /* @var $filterGroupDao FilterGroupDAO */
470  $filterGroup =& $filterGroupDao->getObjectById($filterGroupId);
471  assert(is_a($filterGroup, 'FilterGroup'));
472 
473  // Instantiate the filter
474  $filter =& instantiate($filterClassName, 'PersistableFilter', null, 'execute', $filterGroup); /* @var $filter PersistableFilter */
475  if (!is_object($filter)) fatalError('Error while instantiating class "'.$filterClassName.'" as filter!');
476 
477  return $filter;
478  }
479 
487  function &_fromRow(&$row) {
488  static $lockedFilters = array();
489  $filterId = $row['filter_id'];
490 
491  // Check the filter lock (to detect loops).
492  // NB: This is very important otherwise the request
493  // could eat up lots of memory if the PHP memory max was
494  // set too high.
495  if (isset($lockedFilters[$filterId])) fatalError('Detected a loop in the definition of the filter with id '.$filterId.'!');
496 
497  // Lock the filter id.
498  $lockedFilters[$filterId] = true;
499 
500  // Instantiate the filter.
501  $filter =& $this->_newDataObject($row['class_name'], (integer)$row['filter_group_id']);
502 
503  // Configure the filter instance
504  $filter->setId((int)$row['filter_id']);
505  $filter->setDisplayName($row['display_name']);
506  $filter->setIsTemplate((boolean)$row['is_template']);
507  $filter->setParentFilterId((int)$row['parent_filter_id']);
508  $filter->setSeq((int)$row['seq']);
509  $this->getDataObjectSettings('filter_settings', 'filter_id', $row['filter_id'], $filter);
510 
511  // Recursively retrieve sub-filters of this filter.
512  $this->_populateSubFilters($filter);
513 
514  // Release the lock on the filter id.
515  unset($lockedFilters[$filterId]);
516 
517  return $filter;
518  }
519 
525  function _populateSubFilters(&$parentFilter) {
526  if (!is_a($parentFilter, 'CompositeFilter')) {
527  // Nothing to do. Only composite filters
528  // can have sub-filters.
529  return;
530  }
531 
532  // Retrieve the sub-filters from the database.
533  $parentFilterId = $parentFilter->getId();
534  $result =& $this->retrieve(
535  'SELECT * FROM filters WHERE parent_filter_id = ? ORDER BY seq',
536  (int) $parentFilterId
537  );
538  $daoResultFactory = new DAOResultFactory($result, $this, '_fromRow', array('filter_id'));
539 
540  // Add sub-filters.
541  while (!$daoResultFactory->eof()) {
542  // Retrieve the sub filter.
543  // NB: This recursively loads sub-filters
544  // of this filter via _fromRow().
545  $subFilter =& $daoResultFactory->next();
546 
547  // Add the sub-filter to the filter list
548  // of its parent filter.
549  $parentFilter->addFilter($subFilter);
550  unset($subFilter);
551  }
552  }
553 
559  function _insertSubFilters(&$parentFilter) {
560  if (!is_a($parentFilter, 'CompositeFilter')) {
561  // Nothing to do. Only composite filters
562  // can have sub-filters.
563  return;
564  }
565 
566  // Recursively insert sub-filters
567  foreach($parentFilter->getFilters() as $subFilter) {
568  $subFilter->setParentFilterId($parentFilter->getId());
569  $subfilterId = $this->insertObject($subFilter);
570  assert(is_numeric($subfilterId));
571  }
572  }
573 
579  function _deleteSubFiltersByParentFilterId(&$parentFilterId) {
580  $parentFilterId = (int)$parentFilterId;
581 
582  // Identify sub-filters.
583  $result =& $this->retrieve(
584  'SELECT * FROM filters WHERE parent_filter_id = ?',
585  (int) $parentFilterId
586  );
587 
588  $allSubFilterRows = $result->GetArray();
589  foreach($allSubFilterRows as $subFilterRow) {
590  // Delete sub-filters
591  // NB: We need to do this before we delete
592  // sub-sub-filters to avoid loops.
593  $subFilterId = $subFilterRow['filter_id'];
594  $this->deleteObjectById($subFilterId);
595 
596  // Recursively delete sub-sub-filters.
597  $this->_deleteSubFiltersByParentFilterId($subFilterId);
598  }
599  }
600 }
601 
602 ?>
& getObjectsByTypeDescription($inputTypeDescription, $outputTypeDescription, $data=null, $dataIsInput=true)
Operations for retrieving and modifying objects from a database.
Definition: DAO.inc.php:29
_insertSubFilters(&$parentFilter)
& retrieve($sql, $params=false, $callHooks=true)
Definition: DAO.inc.php:83
getAdditionalFieldNames()
updateDataObjectSettings($tableName, &$dataObject, $idArray)
& configureObject($filterClassName, $filterGroupSymbolic, $settings=array(), $asTemplate=false, $contextId=0, $subFilters=array(), $persist=true)
& getObjectById($filterId, $allowSubfilter=false)
& _fromRow(&$row)
& getObjectsByClass($className, $contextId=CONTEXT_ID_NONE, $getTemplates=false, $allowSubfilters=false)
_deleteSubFiltersByParentFilterId(&$parentFilterId)
& _newDataObject($filterClassName, $filterGroupId)
Wrapper around ADORecordSet providing &quot;factory&quot; features for generating objects from DAOs...
deleteObject(&$filter)
_populateSubFilters(&$parentFilter)
& getDAO($name, $dbconn=null)
insertObject(&$filter, $contextId=CONTEXT_ID_NONE)
Operations for retrieving and modifying Filter objects.
& getObjectsByGroupAndClass($groupSymbolic, $className, $contextId=CONTEXT_ID_NONE, $getTemplates=false, $allowSubfilters=false)
deleteObjectById($filterId)
& getObject(&$filter)
update($sql, $params=false, $callHooks=true, $dieOnError=true)
Definition: DAO.inc.php:211
& getObjectsByGroup($groupSymbolic, $contextId=CONTEXT_ID_NONE, $getTemplates=false, $checkRuntimeEnvironment=true)
updateObject(&$filter)