Open Monograph Press  1.1
 All Classes Namespaces Functions Variables Groups Pages
CompositeFilter.inc.php
1 <?php
16 import('lib.pkp.classes.filter.PersistableFilter');
17 
20  var $_filters = array();
21 
23  var $_maxSeq = 0;
24 
30  function CompositeFilter(&$filterGroup, $displayName = null) {
31  $this->setDisplayName($displayName);
32  parent::PersistableFilter($filterGroup);
33  }
34 
35  //
36  // Getters and Setters
37  //
50  function addFilter(&$filter) {
51  assert(is_a($filter, 'Filter'));
52 
53  // Identify an appropriate sequence number.
54  $seq = $filter->getSeq();
55  if (is_numeric($seq) && $seq > 0) {
56  // This filter has a pre-set sequence number
57  if (isset($this->_filters[$seq])) return null;
58  if ($seq > $this->_maxSeq) $this->_maxSeq = $seq;
59  } else {
60  // We'll create a sequence number for the filter
61  $this->_maxSeq++;
62  $seq = $this->_maxSeq;
63  $filter->setSeq($seq);
64  }
65 
66  // Add the filter to the list.
67  $this->_filters[$seq] =& $filter;
68  return $seq;
69  }
70 
77  function &getFilter($seq) {
78  $filter = null;
79  if (isset($this->_filters[$seq])) {
80  $filter =& $this->_filters[$seq];
81  }
82  return $filter;
83  }
84 
89  function &getFilters() {
90  return $this->_filters;
91  }
92 
117  function setSettingsMapping($settingsMapping) {
118  $this->setData('settingsMapping', $settingsMapping);
119  }
120 
124  function getSettingsMapping() {
125  $settingsMapping = $this->getData('settingsMapping');
126  if (is_null($settingsMapping)) {
127  return array();
128  } else {
129  return $settingsMapping;
130  }
131  }
132 
137  function getSettingsMappingForSetting($settingName) {
138  $settingsMapping = array();
139  $settingsMappingData = $this->getData('settingsMapping');
140  if (isset($settingsMappingData[$settingName])) {
141  $settingsMapping = $settingsMappingData[$settingName];
142  }
143  return $settingsMapping;
144  }
145 
146 
147  //
148  // Overridden methods from PersistableFilter
149  //
153  function &getSetting($settingName) {
154  // Try first whether we have the setting locally.
155  if (parent::hasSetting($settingName)) return parent::getSetting($settingName);
156 
157  // Otherwise expect a mapped setting.
158  return $this->_getSubfilterSetting($settingName);
159  }
160 
164  function &getSettings() {
165  // Get local settings.
166  $settings = parent::getSettings();
167 
168  // Get mapped settings.
169  foreach($this->getSettingsMapping() as $settingName => $mappedSetting) {
170  $settings[] = $this->_getSubfilterSetting($settingName);
171  }
172 
173  return $settings;
174  }
175 
179  function hasSettings() {
180  // Return true if this filter has own
181  // or mapped settings.
182  $settingsMapping = $this->getSettingsMapping();
183  return (parent::hasSettings() || !empty($settingsMapping));
184  }
189  function getSettingNames() {
190  // Composite filters persist only
191  // their own settings. Mapped settings
192  // will be persisted in sub-filters.
193  // We cannot use the parent implementation
194  // here as this would include all sub-
195  // filter settings.
196 
197  // Initialize with the internal settingsMapping
198  // setting.
199  $settingNames = array('settingsMapping');
200 
201  // Read only local settings.
202  foreach(parent::getSettings() as $setting) {
203  if (!$setting->getIsLocalized()) {
204  $settingNames[] = $setting->getName();
205  }
206  }
207  return $settingNames;
208  }
209 
213  function getLocalizedSettingNames() {
214  // We cannot use the parent implementation
215  // here as this would include all sub-
216  // filter settings.
217  $localizedSettingNames = array();
218  foreach(parent::getSettings() as $setting) {
219  if ($setting->getIsLocalized()) {
220  $localizedSettingNames[] = $setting->getName();
221  }
222  }
223  return $localizedSettingNames;
224  }
225 
229  function getInternalSettings() {
230  $filterInternalSettings = parent::getInternalSettings();
231  $filterInternalSettings[] = 'settingsMapping';
232  return $filterInternalSettings;
233  }
234 
236  //
237  // Overridden methods from Filter
238  //
243  // Return false if any of the sub-filters is not compatible.
244  foreach ($this->getFilters() as $filter) {
245  if (!$filter->isCompatibleWithRuntimeEnvironment()) return false;
246  }
247  return true;
248  }
249 
250 
251  //
252  // Overridden methods from DataObject
253  //
257  function &getData($key, $locale = null) {
258  // Directly read local settings.
259  if (in_array($key, $this->getInternalSettings()) || in_array($key, $this->getSettingNames())) return parent::getData($key, $locale);
260 
261  // All other settings will be delegated to sub-filters.
262  $compositeSettingName = $this->_getCompositeSettingName($key);
263  list($filter, $settingName) = $this->_resolveCompositeSettingName($compositeSettingName);
264  return $filter->getData($settingName, $locale);
265  }
266 
270  function setData($key, $value, $locale = null) {
271  // Directly write internal settings.
272  if (is_null($locale)) {
273  if (in_array($key, $this->getInternalSettings()) || in_array($key, $this->getSettingNames())) return parent::setData($key, $value);
274  } else {
275  if (in_array($key, $this->getLocalizedSettingNames())) return parent::setData($key, $value, $locale);
276  }
277 
278  // All other settings will be delegated to sub-filters.
279  $settingsMapping = $this->getSettingsMappingForSetting($key);
280  if (!is_array($settingsMapping)) $settingsMapping = array($settingsMapping);
281  foreach($settingsMapping as $compositeSettingName) {
282  // Write the setting to the sub-filter.
283  list($filter, $settingName) = $this->_resolveCompositeSettingName($compositeSettingName);
284  $filter->setData($settingName, $value, $locale);
285  }
286  }
287 
291  function hasData($key, $locale = null) {
292  // Internal settings will only be checked locally.
293  if (in_array($key, $this->getInternalSettings())) return parent::hasData($key);
294 
295  // Now try local settings.
296  if (parent::hasData($key, $locale)) return true;
298  // If nothing is found we try sub-filter settings.
299  $compositeSettingName = $this->_getCompositeSettingName($key);
300  if (is_null($compositeSettingName)) return false;
301  list($filter, $settingName) = $this->_resolveCompositeSettingName($compositeSettingName);
302  return $filter->hasData($settingName, $locale);
303  }
304 
305 
306  //
307  // Private helper methods
308  //
318  function _getCompositeSettingName($settingName) {
319  $compositeSettingName = $this->getSettingsMappingForSetting($settingName);
320  if (empty($compositeSettingName)) return null;
321  if (is_array($compositeSettingName)) $compositeSettingName = $compositeSettingName[0];
322  return $compositeSettingName;
323  }
334  function &_getSubfilterSetting($settingName) {
335  // Resolve the setting name and retrieve the setting by name.
336  $compositeSettingName = $this->_getCompositeSettingName($settingName);
337  list($filter, $settingName) = $this->_resolveCompositeSettingName($compositeSettingName);
338  return $filter->getSetting($settingName);
339  }
348  function _resolveCompositeSettingName($compositeSettingName) {
349  assert(is_string($compositeSettingName));
350 
351  // The key should be of the
352  // form filterSeq-settingName.
353  $compositeSettingNameParts = explode('_', $compositeSettingName, 2);
354  if (count($compositeSettingNameParts) != 2) fatalError('Invalid composite setting name "'.$compositeSettingName.'"!');
355  list($seq, $settingName) = $compositeSettingNameParts;
356  $seq = str_replace('seq', '', $seq);
357  if (!is_numeric($seq)) fatalError('Invalid sequence number in "'.$compositeSettingName.'"!');
358  $seq = (integer)$seq;
359 
360  // Identify the sub-filter.
361  $filter =& $this->getFilter($seq);
362  if (is_null($filter)) fatalError('Invalid filter sequence number!');
363 
364  // Return the result.
365  return array(&$filter, $settingName);
366  }
367 }
368 ?>
_getCompositeSettingName($settingName)
hasData($key, $locale=null)
_resolveCompositeSettingName($compositeSettingName)
& _getSubfilterSetting($settingName)
setDisplayName($displayName)
Definition: Filter.inc.php:140
An abstract base class for generic filters that compose other filters into filter networks...
A filter that can be persisted to the database.
setSettingsMapping($settingsMapping)
& getSetting($settingName)
& getData($key, $locale=null)
CompositeFilter(&$filterGroup, $displayName=null)
getSettingsMappingForSetting($settingName)
setData($key, $value, $locale=null)