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

  • AdditionalMenuWidget_Item
  • AdvancedSliderHomepageWidget_Item
  • AssetManagerFolder
  • BannerWidget_Item
  • BaseObjectDecorator
  • BookingOrder
  • BookingPaymentMethod
  • BookingService
  • Boolean
  • ButtonsBlockHomepageWidget_Item
  • CarouselHomepageWidget_Item
  • CatalogFilter
  • CatalogRubricsHomepageWidget_CatalogDecorator
  • ClientEmailOrderNotification
  • ClientVKOrderNotification
  • ComponentSet
  • Currency
  • DatabaseAdmin
  • DataObject
  • DataObjectDecorator
  • DataObjectLog
  • DataObjectSet
  • DataObjectSet_Iterator
  • Date
  • DB
  • DBField
  • Decimal
  • DocumentItem
  • DocumentPage_File
  • Double
  • Enum
  • ErrorPageSubsite
  • FileDataObjectTrackingDecorator
  • FileImportDecorator
  • Float
  • FlowerGarden_Size
  • ForeignKey
  • Hierarchy
  • HouseCatalogProductDecorator
  • HTMLText
  • HTMLVarchar
  • Import1CLog
  • Import1CLog_File
  • Import1CLog_Item
  • Import1CLog_Task
  • ImportCatalog1C_PriceType
  • ImportCatalog1C_ProductProp
  • Int
  • ManagerEmailOrderNotification
  • Material3D_File
  • MediawebPage_File
  • MediawebPage_Photo
  • MobileContentDecorator
  • Money
  • MonumentGalleryItem
  • MonumentPhotoGallery
  • MultiEnum
  • MySQLDatabase
  • MySQLQuery
  • Notification
  • OrderDataObject
  • OrderDecorator
  • OrderHandlersDecorator
  • OrderItemDecorator
  • OrderItemVariationDecorator
  • Orders1CExchange_OrdersDecorator
  • OrderService
  • OrderServiceOrder
  • PageIcon
  • PageWidgets
  • Payment
  • PaymentMethodShippingDecorator
  • PaymentOrderExtension
  • Percentage
  • Person
  • PhotoAlbumItem
  • PhotoAlbumProductLinkDecorator
  • PhotoAlbumWidgetLinkDecorator
  • PhotoGalleryHomepageWidget_Item
  • PortraitType
  • PrimaryKey
  • Product3DDecorator
  • ProductCatalogCatalogLinkedDecorator
  • ProductImportLog
  • ProductImportLog_Item
  • ProductParam
  • ProductParamValue
  • ProductVariation
  • RatePeriod
  • RealtyImportLog
  • RealtyImportLog_Item
  • RedirectEntry
  • RoomOrder
  • RoomOrderPerson
  • RoomRate
  • RoomService
  • RoomServiceOrder
  • SberbankPaymentDecorator
  • SeoOpenGraphPageDecorator
  • ServiceOrder
  • ShippingMethodPaymentDecorator
  • ShopCountry
  • SimpleOrderCatalogDecorator
  • SimpleOrderProductDecorator
  • SiteConfigWidgets
  • SiteTreeDecorator
  • SiteTreeImportDecorator
  • SliderHomepageWidget_Item
  • SMSCOrderNotification
  • SMSOrderNotification
  • SortableDataObject
  • SQLMap
  • SQLMap_Iterator
  • SQLQuery
  • SS_Database
  • SS_Datetime
  • SS_Query
  • StringField
  • SubsiteDomain
  • Text
  • TextAnonsWidget_Item
  • Texture3D_File
  • Time
  • Varchar
  • Versioned
  • Versioned_Version
  • VideoCategory
  • VideoEntry
  • VKNotificationQueue
  • WebylonWidget_Item
  • YaMoneyPaymentDecorator
  • Year

Interfaces

  • CompositeDBField
  • CurrentPageIdentifier
  • DataObjectInterface
  1 <?php
  2 // вариация продукта 
  3 class ProductVariation extends DataObject {
  4     static $db = array(
  5         'Title' => 'Varchar(200)',     // полное название вариации для корзины   
  6         'MenuTitle' => 'Varchar(200)', // краткое название вариации для списка выбора, может формироваться автоматически как склеивание пар: название параметра: значение параметра
  7         
  8         'PriceType' => "Enum('own,delta,percent')", // "тип цены" с вариантами (своя цена, разница в руб., наценка в %)
  9         
 10         'BasePriceDelta' => 'CatalogPrice', // разница в руб
 11         'CostPriceDelta' => 'CatalogPrice', // разница в руб
 12         
 13         'BasePricePercent' => 'Float', // наценка в %
 14         'CostPricePercent' => 'Float', // наценка в %
 15                 
 16         'BasePriceOwn' => 'CatalogPrice', // Обычная цена
 17         'CostPriceOwn' => 'CatalogPrice', // Цена по акции
 18         
 19         'VariationPrice' => 'CatalogPrice', // Итоговая цена вариации (техническое поле)
 20         
 21         'Available' => 'Boolean', // Флаг доступности
 22         'AllowPurchase' => 'Boolean', // Флаг "можно заказывать"
 23         
 24         'ImportID' => 'Varchar(100)', // ID-импорта, нигде не редактируется и не отображается используется только для импорта
 25         'SKU' => 'Varchar', // Артикул товара
 26         
 27         'Quantity' => 'Int', // остаток на складе
 28         'Sort' => 'Int', // сортировка
 29     );
 30     
 31     static $has_one = array(
 32         'Product' => 'Product',
 33     );
 34     
 35     static $has_many = array(
 36         'ParamValues' => 'ProductParamValue',
 37     );
 38     
 39     static $searchable_fields = array('Title', 'Available', 'AllowPurchase', 'Quantity', 'VariationPrice');
 40     
 41     static $summary_fields = array('Title', 'Available', 'AllowPurchase', 'Quantity', 'CostPrice', 'BasePrice', 'VariationPrice');
 42     
 43     static $default_sort = "Sort";
 44     
 45     function fieldLabels() {
 46         $labels = parent::fieldLabels();
 47         $labels['CostPrice'] = $labels['CostPriceOwn'];
 48         $labels['BasePrice'] = $labels['BasePriceOwn'];
 49         return $labels;
 50     }
 51     
 52     function getCMSFields() {
 53         $fields = parent::getCMSFields();
 54         $tab = $fields->findOrMakeTab('Root.Main');
 55         $fields->removeByName('VariationPrice');
 56 
 57         $fields->removeByName('ParamValues');
 58         $fields->removeByName('PriceType');
 59         
 60         $bp = $fields->dataFieldByName('BasePriceOwn');
 61         $cp = $fields->dataFieldByName('CostPriceOwn');
 62         $pf = new FieldGroup($bp, $cp);
 63         $fields->removeByName('BasePriceOwn');
 64         $fields->removeByName('CostPriceOwn');
 65                         
 66         $bpd = $fields->dataFieldByName('BasePriceDelta');
 67         $cpd = $fields->dataFieldByName('CostPriceDelta');
 68         $pfd = new FieldGroup($bpd, $cpd);
 69         $fields->removeByName('BasePriceDelta');
 70         $fields->removeByName('CostPriceDelta');
 71         
 72         $bpp = $fields->dataFieldByName('BasePricePercent');
 73         $cpp = $fields->dataFieldByName('CostPricePercent');
 74         $pfp = new FieldGroup($bpp, $cpp);
 75         $fields->removeByName('BasePricePercent');
 76         $fields->removeByName('CostPricePercent');
 77         
 78         $tab->insertBefore($type = new SelectionGroup('PriceType', array(
 79             'own//' . _t('ProductVariation.PriceType_own', 'Price Type Own') => $pf,
 80             'delta//' . _t('ProductVariation.PriceType_delta', 'Price Type Currency Diff') => $pfd,
 81             'percent//' . _t('ProductVariation.PriceType_percent', 'Price Type Percents Diff') => $pfp,
 82         )), 'Available');
 83         
 84         if ($this->ProductID && $this->ID && $categoryParams = $this->Product()->Parent()->getVariationCatalogParams()) {       
 85             foreach($categoryParams as $categoryParam) {
 86                 if ($categoryParam->Type == 'bool') {
 87                     $tab->push(new ProductParamValue_BoolValueField('ParamValues', $categoryParam, $this->ID, 'ProductVariationID'));
 88                 } else {
 89                     if ($categoryParam->MultiValues) {
 90                         if ($categoryParam->PossibleValuesList()) {
 91                             $tab->push(new ProductParamValue_MultiValueSetField('ParamValues', $categoryParam, $this->ID, 'ProductVariationID'));
 92                         } else {
 93                             $tab->push(new LiteralField('ParamTitle', "<h4>{$categoryParam->Title}</h4>"));
 94                             $rate = new ProductParamValue();
 95                             $fieldList = array(                             
 96                                 "Value" => $rate->fieldLabel('Value'),                                  
 97                             );  
 98                             $fieldTypes = array(                                
 99                                 'Value' => 'TextField',             
100                             );
101                             $ctf = new TableField("ParamValues", "ProductParamValue", $fieldList, $fieldTypes, 'ProductParamID', $categoryParam->ID);
102                             $params = new DataObjectSet();
103                             if ($allParamValues = DataObject::get('ProductParamValue', "ProductParamID = {$categoryParam->ID} AND ProductID = {$this->ID}")) {
104                                 $params = $allParamValues;
105                             }
106                             $ctf->setCustomSourceItems($params);
107                             $tab->push($ctf);
108                         }
109                     } else {
110                         if ($categoryParam->PossibleValuesList()) {
111                             $tab->push(new ProductParamValue_MultiValueField('ParamValues', $categoryParam, $this->ID, 'ProductVariationID'));
112                         } else {
113                             $tab->push(new ProductParamValue_ValueField('ParamValues', $categoryParam, $this->ID, 'ProductVariationID'));
114                         }
115                     }
116                 }
117                 //$paramValues->push($t);
118             }
119         }
120         return $fields;
121     }
122     
123     function OrderButtonTitle() {
124         if ($this->MenuTitle) {
125             return $this->MenuTitle;
126         }
127         return $this->Title;
128     }   
129     
130     // флаг для верстки
131     function IsVariation() {
132         return true;
133     }
134     
135     function getPhoto() {
136         return $this->Product()->Photo();
137     }
138     
139     function getBasePrice() {
140         $price = 0;
141         if ($this->ProductID && ($product = $this->Product())) {
142             switch ($this->PriceType) {
143                 case 'own':
144                     $price = $this->BasePriceOwn;
145                     break;
146                 case 'delta':
147                     $price = $product->BasePrice + $this->BasePriceDelta;
148                     break;
149                 case 'percent':
150                     $price = $product->BasePrice + $product->BasePrice  / 100 * $this->BasePricePercent;
151                     break;
152             }           
153         }
154         return $price;
155     }
156     
157     function getCostPrice() {
158         $price = 0;
159         if ($this->ProductID && ($product = $this->Product())) {
160             switch ($this->PriceType) {
161                 case 'own':
162                     $price = $this->CostPriceOwn;
163                     break;
164                 case 'delta':
165                     if ((int)$product->CostPrice) {
166                         $price = $product->CostPrice + $this->CostPriceDelta;
167                     }
168                     break;
169                 case 'percent':
170                     if ((int)$product->CostPrice) {
171                         $price = $product->CostPrice + $product->CostPrice  / 100 * $this->CostPricePercent;
172                     }
173                     break;
174             }
175         }
176         return $price;
177     }
178     
179     function NiceBasePrice() {
180         return DBField::create('CatalogPrice', $this->getBasePrice());
181     }
182     
183     function NiceCostPrice() {
184         return DBField::create('CatalogPrice', $this->getCostPrice());
185     }
186     
187     function Price($onlyreal=false) {
188         $real = $this->VariationPrice;
189         $client = $real;
190         $delta = 0;
191         $percent = 0;
192         if ($this->CostPrice == 0) {
193             // персональная скидка
194             $member = Member::currentUser();
195             if ($member){
196                 if ($member->hasMethod('getPersonalDiscount') && $percent < $member->getPersonalDiscount()) {
197                     $percent = $member->getPersonalDiscount();
198                 }
199                 // групповые скидки
200                 if ($groups = $member->Groups()) {
201                     foreach ($groups as $g) {
202                         if ($g->hasMethod('Discount') && $percent < $g->Discount()) {
203                             $percent = $g->Discount();
204                         }
205                     }
206                 }
207             }
208             $this->extend('updateDiscount', $percent);
209         }
210         $sc = SiteConfig::current_site_config();
211         $ceil = $sc->CatalogDiscountCeil;       
212         if ($ceil) {
213             $real = ceil($real);
214             $client = ceil($client);
215             $decimal = 0;
216         }       
217         if ($percent) {
218             $delta = ($ceil) ? ceil(($real / 100) * $percent) : round(($real / 100) * $percent, 2);
219             $client = $real - $delta;
220         }       
221         if ($onlyreal) {
222             return $client;
223         }       
224         return new ArrayData(array(
225             'Real' => DBField::create('CatalogPrice', $real),
226             'Client' => DBField::create('CatalogPrice', $client),
227             'Delta' => DBField::create('CatalogPrice', $delta),
228             'Percent' => $percent,
229             'Discount' => ($percent > 0) ? 1 : 0,
230             'Currency' => $sc->CatalogCurrency,
231         ));
232         
233         return DBField::create('CatalogPrice', ($this->CostPrice > 0) ? $this->CostPrice : $this->BasePrice);
234     }
235     /*
236     function getVariationPrice() {
237         return $this->Price();
238     }
239     */
240     
241     function onBeforeWrite() {
242         parent::onBeforeWrite();
243         $this->VariationPrice = ($this->CostPrice > 0) ? $this->CostPrice : $this->BasePrice;
244         /* !! Сомнительно, уточнить !!!
245         if ($this->Quantity <= 0) {
246             $this->Available = 0;
247             $this->AllowPurchase = 0;
248         }
249         */
250     }
251     
252     function onAfterDelete() {
253         parent::onAfterDelete();
254             
255         DB::Query("DELETE FROM `ProductParamValue` WHERE ProductVariationID = {$this->ID}");
256     }
257     
258     // Список параметров для вывода на карточке товара
259     function ParamValue($title) {
260         if ($product = $this->Product()) {
261             $join = "JOIN ProductParam ON ProductParam.ID = ProductParamValue.ProductParamID";
262             if ($product->Parent()->OwnParams) {
263                 $join .= " JOIN Catalog_EnabledParams ON ProductParam.ID = Catalog_EnabledParams.ProductParamID AND Catalog_EnabledParams.CatalogID = {$product->ParentID}";
264             }
265             $title = Convert::raw2sql($title);
266             $value = DataObject::get('ProductParamValue', "ProductVariationID = {$this->ID} AND ProductParam.TechTitle = '{$title}' ", "", $join);
267             if ($value) {
268                 return $value->First();
269             }
270         }
271         return false;
272     }
273     
274     /**
275      * Возвращает класс для кнопки заказа товара в зависимости от цены и значений Product::$empty_order_button_class и Product::$order_button_class
276      * 
277      * @return string
278      */
279     function orderButtonClass() {
280         if (!$this->AllowPurchase) {
281             return false;
282         }
283         if ($this->VariationPrice == 0) {
284             if (Product::$order_empty_price)
285                 return Product::$empty_order_button_class;
286             return false;
287         }
288         $class = Product::$order_button_class;
289         $this->extend('updateOrderButtonClass', $class);
290         return $class;
291     }
292 
293     /**
294      * Возвращает объект для генерации кнопки заказа
295      * 
296      * @return OrderButtonInterface
297      */ 
298     function OrderButton() {        
299         $buttonClass = $this->orderButtonClass();       
300         if (!$buttonClass) 
301             return false;
302         return new $buttonClass($this->ProductID, $this->ID);
303     }
304     
305     /**
306      * Возвращает html для кнопки заказа товара с оплем для кол-ва
307      * 
308      * @return string
309      */
310     function OrderButtonWithNum() {
311         if ($button = $this->OrderButton()) {           
312             return $button->WithNum();
313         }
314         return false;
315     }
316     
317     function OrderButtonLink() {
318         return $this->Product()->VariationOrderButtonLink($this->ID);
319     }
320     
321     function PurchaseStatus() {     
322         if (!$this->Available && !$this->AllowPurchase) {
323             return 'NoOrder';
324         }
325         if (!$this->Available && $this->AllowPurchase) {
326             return 'PreOrder';
327         }
328         if ($this->Available && !$this->AllowPurchase) {
329             return 'NoOrder';
330         }
331         if ($this->Available && $this->AllowPurchase) {
332             return 'InStock';
333         }
334         return 'NoOrder';
335     }
336     
337     function PurchaseStatusTitle() {
338         return _t('ProductVariation.PurchaseStatus_' . $this->PurchaseStatus());
339     }
340     
341     function canOrder() {
342         if (in_array($this->PurchaseStatus(), array('PreOrder', 'InStock'))) {
343             return true;
344         }
345         return false;
346     }
347     
348     function VariationInfo() {
349         $info = array();
350         $info['Title'] = $this->Title;
351         $info['Available'] = (bool)$this->Available;
352         $info['AllowPurchase'] = (bool)$this->AllowPurchase;
353         $info['SKU'] = $this->SKU;
354         $info['Quantity'] = (int)$this->Quantity;
355         $info['CostPrice'] = (float)$this->getCostPrice();
356         $info['BasePrice'] = (float)$this->getBasePrice();
357         $info['Price'] = (float)$this->Price(1);
358         return $info;
359     }
360     
361     //this is used by TableListField to access attribute values.
362     function AttributeProxy(){
363         $do = new DataObject();
364         if($this->ParamValues()->exists()){
365             foreach($this->ParamValues() as $value){
366                 $do->{'Val'.$value->TechTitle} = $value->Value;             
367             }
368         }
369         return $do;
370     }
371 
372 }
[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