Webylon 3.1 API Docs
  • Package
  • Class
  • Tree
  • Deprecated
  • Download
Version: current
  • 3.2
  • 3.1

Packages

  • auth
  • Booking
  • cart
    • shipping
    • steppedcheckout
  • Catalog
  • cms
    • assets
    • batchaction
    • batchactions
    • bulkloading
    • comments
    • content
    • core
    • export
    • newsletter
    • publishers
    • reports
    • security
    • tasks
  • Dashboard
  • DataObjectManager
  • event
  • faq
  • forms
    • actions
    • core
    • fields-basic
    • fields-dataless
    • fields-datetime
    • fields-files
    • fields-formatted
    • fields-formattedinput
    • fields-relational
    • fields-structural
    • transformations
    • validators
  • googlesitemaps
  • guestbook
  • installer
  • newsletter
  • None
  • photo
    • gallery
  • PHP
  • polls
  • recaptcha
  • sapphire
    • api
    • bulkloading
    • control
    • core
    • cron
    • dev
    • email
    • fields-formattedinput
    • filesystem
    • formatters
    • forms
    • i18n
    • integration
    • misc
    • model
    • parsers
    • search
    • security
    • tasks
    • testing
    • tools
    • validation
    • view
    • widgets
  • seo
    • open
      • graph
  • sfDateTimePlugin
  • spamprotection
  • stealth
    • captha
  • subsites
  • userform
    • pagetypes
  • userforms
  • webylon
  • widgets

Classes

  • AdvancedSearchForm
  • ContentControllerSearchExtension
  • EndsWithFilter
  • ExactMatchFilter
  • ExactMatchMultiFilter
  • FulltextFilter
  • FulltextSearchable
  • GreaterThanFilter
  • LessThanFilter
  • NegationFilter
  • PartialMatchFilter
  • SearchContext
  • SearchFilter
  • SearchForm
  • StartsWithFilter
  • StartsWithMultiFilter
  • SubstringFilter
  • WithinRangeFilter
  1 <?php
  2 /**
  3 * Manages searching of properties on one or more {@link DataObject}
  4 * types, based on a given set of input parameters.
  5 * SearchContext is intentionally decoupled from any controller-logic,
  6 * it just receives a set of search parameters and an object class it acts on.
  7 * 
  8 * The default output of a SearchContext is either a {@link SQLQuery} object
  9 * for further refinement, or a {@link DataObjectSet} that can be used to display
 10 * search results, e.g. in a {@link TableListField} instance.
 11 * 
 12 * In case you need multiple contexts, consider namespacing your request parameters
 13 * by using {@link FieldSet->namespace()} on the $fields constructor parameter.
 14 * 
 15 * Each DataObject subclass can have multiple search contexts for different cases,
 16 * e.g. for a limited frontend search and a fully featured backend search.
 17 * By default, you can use {@link DataObject->getDefaultSearchContext()} which is automatically
 18 * scaffolded. It uses {@link DataObject::$searchable_fields} to determine which fields
 19 * to include.
 20 * 
 21 * @see http://doc.silverstripe.com/doku.php?id=searchcontext
 22 *
 23 * @package sapphire
 24 * @subpackage search
 25 */
 26 class SearchContext extends Object {
 27     
 28     /**
 29      * DataObject subclass to which search parameters relate to.
 30      * Also determines as which object each result is provided.
 31      *
 32      * @var string
 33      */
 34     protected $modelClass;
 35     
 36     /**
 37      * FormFields mapping to {@link DataObject::$db} properties
 38      * which are supposed to be searchable.
 39      *
 40      * @var FieldSet
 41      */
 42     protected $fields;
 43     
 44     /**
 45      * Array of {@link SearchFilter} subclasses.
 46      *
 47      * @var array
 48      */
 49     protected $filters;
 50     
 51     /**
 52      * The logical connective used to join WHERE clauses. Defaults to AND.
 53      * @var string
 54      */
 55     public $connective = 'AND';
 56     
 57     /**
 58      * A key value pair of values that should be searched for.
 59      * The keys should match the field names specified in {@link self::$fields}.
 60      * Usually these values come from a submitted searchform
 61      * in the form of a $_REQUEST object.
 62      * CAUTION: All values should be treated as insecure client input.
 63      * 
 64      * @param string $modelClass The base {@link DataObject} class that search properties related to.
 65      *                      Also used to generate a set of result objects based on this class.
 66      * @param FieldSet $fields Optional. FormFields mapping to {@link DataObject::$db} properties
 67      *                      which are to be searched. Derived from modelclass using 
 68      *                      {@link DataObject::scaffoldSearchFields()} if left blank.
 69      * @param array $filters Optional. Derived from modelclass if left blank
 70      */ 
 71     function __construct($modelClass, $fields = null, $filters = null) {
 72         $this->modelClass = $modelClass;
 73         $this->fields = ($fields) ? $fields : new FieldSet();
 74         $this->filters = ($filters) ? $filters : array();
 75         
 76         parent::__construct();
 77     }
 78         
 79     /**
 80      * Returns scaffolded search fields for UI.
 81      *
 82      * @return FieldSet
 83      */
 84     public function getSearchFields() {
 85         return ($this->fields) ? $this->fields : singleton($this->modelClass)->scaffoldSearchFields();
 86         // $this->fields is causing weirdness, so we ignore for now, using the default scaffolding
 87         //return singleton($this->modelClass)->scaffoldSearchFields();
 88     }
 89     
 90     /**
 91      * @todo move to SQLQuery
 92      * @todo fix hack
 93      */
 94     protected function applyBaseTableFields() {
 95         $classes = ClassInfo::dataClassesFor($this->modelClass);
 96         $fields = array("\"".ClassInfo::baseDataClass($this->modelClass).'".*');
 97         if($this->modelClass != $classes[0]) $fields[] = '"'.$classes[0].'".*';
 98         //$fields = array_keys($model->db());
 99         $fields[] = '"'.$classes[0].'".\"ClassName\" AS "RecordClassName"';
100         return $fields;
101     }
102     
103     /**
104      * Returns a SQL object representing the search context for the given
105      * list of query parameters.
106      *
107      * @param array $searchParams Map of search criteria, mostly taked from $_REQUEST.
108      *  If a filter is applied to a relationship in dot notation,
109      *  the parameter name should have the dots replaced with double underscores,
110      *  for example "Comments__Name" instead of the filter name "Comments.Name".
111      * @param string|array $sort Database column to sort on. 
112      *  Falls back to {@link DataObject::$default_sort} if not provided.
113      * @param string|array $limit 
114      * @param SQLQuery $existingQuery
115      * @return SQLQuery
116      */
117     public function getQuery($searchParams, $sort = false, $limit = false, $existingQuery = null) {
118         $model = singleton($this->modelClass);
119         
120         if($existingQuery) {
121             $query = $existingQuery;
122         } else {
123             $query = $model->extendedSQL();
124         }
125 
126         $SQL_limit = Convert::raw2sql($limit);
127         $query->limit($SQL_limit);
128 
129         $SQL_sort = (!empty($sort)) ? Convert::raw2sql($sort) : singleton($this->modelClass)->stat('default_sort');     
130         $query->orderby($SQL_sort);
131         
132         // hack to work with $searchParems when it's an Object 
133         $searchParamArray = array();
134         if (is_object($searchParams)) {
135             $searchParamArray = $searchParams->getVars();
136         } else {
137             $searchParamArray = $searchParams;
138         }
139 
140         foreach($searchParamArray as $key => $value) {
141             $key = str_replace('__', '.', $key);
142             if($filter = $this->getFilter($key)) {
143                 $filter->setModel($this->modelClass);
144                 $filter->setValue($value);
145                 if(! $filter->isEmpty()) {
146                     $filter->apply($query);
147                 }
148             }
149         }
150         
151         $query->connective = $this->connective;
152         $query->distinct = true;
153         
154         $model->extend('augmentSQL', $query);
155         
156         return $query;
157     }
158 
159     /**
160      * Returns a result set from the given search parameters.
161      *
162      * @todo rearrange start and limit params to reflect DataObject
163      * 
164      * @param array $searchParams
165      * @param string|array $sort
166      * @param string|array $limit
167      * @return DataObjectSet
168      */
169     public function getResults($searchParams, $sort = false, $limit = false) {
170         $searchParams = array_filter($searchParams, array($this,'clearEmptySearchFields'));
171         
172         $query = $this->getQuery($searchParams, $sort, $limit);
173         
174         // use if a raw SQL query is needed
175         $results = new DataObjectSet();
176         foreach($query->execute() as $row) {
177             $className = $row['RecordClassName'];
178             $results->push(new $className($row));
179         }
180         return $results;
181         //
182         //return DataObject::get($this->modelClass, $query->getFilter(), "", "", $limit);
183     }
184 
185     /**
186      * Callback map function to filter fields with empty values from
187      * being included in the search expression.
188      *
189      * @param unknown_type $value
190      * @return boolean
191      */
192     function clearEmptySearchFields($value) {
193         return ($value != '');
194     }
195         
196     /**
197      * Accessor for the filter attached to a named field.
198      *
199      * @param string $name
200      * @return SearchFilter
201      */
202     public function getFilter($name) {
203         if (isset($this->filters[$name])) {
204             return $this->filters[$name];
205         } else {
206             return null;
207         }
208     }
209     
210     /**
211      * Get the map of filters in the current search context.
212      *
213      * @return array
214      */
215     public function getFilters() {
216         return $this->filters;
217     }
218     
219     /**
220      * Overwrite the current search context filter map.
221      *
222      * @param array $filters
223      */
224     public function setFilters($filters) {
225         $this->filters = $filters;
226     }   
227     
228     /**
229      * Adds a instance of {@link SearchFilter}.
230      *
231      * @param SearchFilter $filter
232      */
233     public function addFilter($filter) {
234         $this->filters[$filter->getFullName()] = $filter;
235     }
236     
237     /**
238      * Removes a filter by name.
239      *
240      * @param string $name
241      */
242     public function removeFilterByName($name) {
243         unset($this->filters[$name]);
244     }
245     
246     /**
247      * Get the list of searchable fields in the current search context.
248      *
249      * @return FieldSet
250      */
251     public function getFields() {
252         return $this->fields; 
253     }
254     
255     /**
256      * Apply a list of searchable fields to the current search context.
257      *
258      * @param FieldSet $fields
259      */
260     public function setFields($fields) {
261         $this->fields = $fields;
262     }
263     
264     /**
265      * Adds a new {@link FormField} instance.
266      *
267      * @param FormField $field
268      */
269     public function addField($field) {
270         $this->fields->push($field);
271     }
272     
273     /**
274      * Removes an existing formfield instance by its name.
275      *
276      * @param string $fieldName
277      */
278     public function removeFieldByName($fieldName) {
279         $this->fields->removeByName($fieldName);
280     }
281     
282 }
283 ?>
284 
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -
Webylon 3.1 API Docs API documentation generated by ApiGen 2.8.0