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

Packages

  • 1c
    • exchange
      • catalog
  • auth
  • Booking
  • building
    • company
  • cart
    • shipping
    • steppedcheckout
  • Catalog
    • monument
  • 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

  • Aggregate
  • Aggregate_Relationship
  • AssetAdminQuotaExtension
  • AttachedFilesExtension
  • BookingWidget
  • ClassInfo
  • ControllerRedirectExtension
  • CSSContentParser
  • DisableJSValidation
  • Extension
  • HtmlEditorQuotaExtension
  • ManifestBuilder
  • MobileExtension
  • Object
  • PaymentMethodAutoHide
  • ProductSearchFormExtension
  • SS_Cache
  • TokenisedRegularExpression
  • ValidationResult
  • WebylonSiteSearchExtension
  • YamlFixture

Functions

  • __autoload
  • _t
  • array_fill_keys
  • getClassFile
  • getSysTempDir
  • getTempFolder
  • increase_memory_limit_to
  • increase_time_limit_to
  • project
  • singleton
  • stripslashes_recursively
  • translate_memstring
  1 <?php
  2 
  3 /**
  4  * Calculate an Aggregate on a particular field of a particular DataObject type (possibly with
  5  * an additional filter before the aggregate)
  6  * 
  7  * Implemented as a class to provide a semi-DSL method of calculating Aggregates. DataObject has a function
  8  * that will create & return an instance of this class with the DataObject type and filter set,
  9  * but at that point we don't yet know the aggregate function or field
 10  * 
 11  * This class captures any XML_val or unknown call, and uses that to get the field & aggregate function &
 12  * then return the result
 13  * 
 14  * Two ways of calling
 15  * 
 16  * $aggregate->XML_val(aggregate_function, array(field))     - For templates
 17  * $aggregate->aggregate_function(field)                     - For PHP
 18  * 
 19  * Aggregate functions are uppercased by this class, but are otherwise assumed to be valid SQL functions. Some
 20  * examples: Min, Max, Avg
 21  * 
 22  * Aggregates are often used as portions of a cacheblock key. They are therefore cached themselves, in the 'aggregate'
 23  * cache, although the invalidation logic prefers speed over keeping valid data.
 24  * 
 25  * NOTE: The cache logic uses tags, and so a backend that supports tags is required. Currently only the File
 26  * backend (and the two-level backend with the File backend as the slow store) meets this requirement
 27  * 
 28  * @author hfried
 29  * @package sapphire
 30  * @subpackage core
 31  */
 32 class Aggregate extends ViewableData {
 33 
 34     static $cache = null;
 35     
 36     /** Build & cache the cache object */
 37     protected static function cache() {
 38         return self::$cache ? self::$cache : (self::$cache = SS_Cache::factory('aggregate'));
 39     }
 40     
 41     /** Clear the aggregate cache for a given type, or pass nothing to clear all aggregate caches */
 42     public static function flushCache($class=null) {
 43         $cache = self::cache();
 44         
 45         if (!$class || $class == 'DataObject') {
 46             $cache->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('aggregate'));
 47         }   
 48         else {
 49             $cache->clean(Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG, ClassInfo::ancestry($class));
 50         }
 51     }
 52     
 53     /**
 54      * Constructor
 55      * 
 56      * @param string $type The DataObject type we are building an aggregate for
 57      * @param string $filter (optional) An SQL filter to apply to the selected rows before calculating the aggregate
 58      */
 59     public function __construct($type, $filter = '') {
 60         $this->type = $type;
 61         $this->filter = $filter;
 62         parent::__construct();
 63     }
 64 
 65     /**
 66      * Build the SQLQuery to calculate the aggregate
 67      * This is a seperate function so that subtypes of Aggregate can change just this bit
 68      * @param string $attr - the SQL field statement for selection (i.e. "MAX(LastUpdated)")
 69      * @return SQLQuery
 70      */
 71     protected function query($attr) {
 72         $singleton = singleton($this->type);
 73         $query = $singleton->buildSQL($this->filter);
 74         $query->select = array($attr);
 75         $query->orderby = null;
 76         $singleton->extend('augmentSQL', $query);
 77         return $query;
 78     }
 79     
 80     /**
 81      * Entry point for being called from a template.
 82      * 
 83      * This gets the aggregate function 
 84      * 
 85      */
 86     public function XML_val($name, $args) {
 87         $func = strtoupper( strpos($name, 'get') === 0 ? substr($name, 3) : $name );
 88         $attribute = $args ? $args[0] : 'ID';
 89         
 90         $table = null;
 91         
 92         foreach (ClassInfo::ancestry($this->type, true) as $class) {
 93             $fields = DataObject::database_fields($class);
 94             if (array_key_exists($attribute, $fields)) { $table = $class; break; }
 95         }
 96         
 97         if (!$table) user_error("Couldn't find table for field $attribute in type {$this->type}", E_USER_ERROR);
 98         
 99         $query = $this->query("$func(\"$table\".\"$attribute\")");
100         
101         $cachekey = sha1($query->sql());
102         $cache = self::cache();
103         
104         if (!($result = $cache->load($cachekey))) {
105             $result = (string)$query->execute()->value(); if (!$result) $result = '0';
106             $cache->save($result, null, array('aggregate', $this->type));
107         }
108         
109         return $result;
110     }
111     
112     /**
113      * Entry point for being called from PHP.
114      */
115     public function __call($method, $arguments) {
116         return $this->XML_val($method, $arguments);
117     }
118 }
119 
120 /**
121  * A subclass of Aggregate that calculates aggregates for the result of a has_many query.
122  * 
123  * @author hfried
124  * @package sapphire
125  * @subpackage core
126  */
127 class Aggregate_Relationship extends Aggregate {
128 
129     /**
130      * Constructor
131      * 
132      * @param DataObject $object The object that has_many somethings that we're calculating the aggregate for 
133      * @param string $relationship The name of the relationship
134      * @param string $filter (optional) An SQL filter to apply to the relationship rows before calculating the aggregate
135      */
136     public function __construct($object, $relationship, $filter = '') {
137         $this->object = $object;
138         $this->relationship = $relationship;
139         
140         $this->has_many = $object->has_many($relationship);
141         $this->many_many = $object->many_many($relationship);
142 
143         if (!$this->has_many && !$this->many_many) user_error("Could not find relationship $relationship on object class {$object->class} in Aggregate Relationship", E_USER_ERROR);
144         
145         parent::__construct($this->has_many ? $this->has_many : $this->many_many[1], $filter);
146     }
147     
148     protected function query($attr) {
149         if ($this->has_many) {
150             $query = $this->object->getComponentsQuery($this->relationship, $this->filter);
151         }
152         else {
153             $query = $this->object->getManyManyComponentsQuery($this->relationship, $this->filter);
154         }
155         
156         $query->select = array($attr);
157         $query->groupby = array();
158         
159         $singleton = singleton($this->type);
160         $singleton->extend('augmentSQL', $query);
161 
162         return $query;
163     }
164 }
165 
[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.2 API Docs API documentation generated by ApiGen 2.8.0