Issues (2002)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

code/config/EcommerceConfigDefinitions.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
4
/**
5
 * This class sets out the static config variables for e-commerce.
6
 * It also adds the definitions of any classes that extend EcommerceConfigDefitions.
7
 *
8
 * @authors: Nicolaas [at] Sunny Side Up .co.nz
9
 * @package: ecommerce
10
 * @sub-package: configuration
11
 * @inspiration: Silverstripe Ltd, Jeremy
12
 **/
13
class EcommerceConfigDefinitions extends Object
14
{
15
    /**
16
     * Tells us what version of e-commerce we are using.
17
     *
18
     * @var float
19
     */
20
    private $version = 1;
21
22
    /**
23
     * Tells us the version of e-commerce in use.
24
     *
25
     * @return int
0 ignored issues
show
Should the return type not be double?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
26
     */
27
    public function Version()
28
    {
29
        return $this->version;
30
    }
31
32
    /**
33
     * LIST of ajax methods.
34
     */
35
    protected $ajaxMethods = array(
36
        'SideBarCartID' => 'The sidebar cart. See CartResponse.cart_responses_required to see if it is being used and what template is being used.',
37
        'SmallCartID' => 'The small cart. See CartResponse.cart_responses_required to see if it is being used and what template is being used.',
38
        'TinyCartClassName' => 'The tiny cart. See CartResponse.cart_responses_required to see if it is being used and what template is being used. ',
39
        'TotalItemsClassName' => 'The total number of items in the order. Use in the following context: AjaxDefinitions.TotalItemsClassName',
40
        'TotalItemsTimesQuantityClassName' => 'The total number of items times their quantity in the order. Use in the following context: AjaxDefinitions.TotalItemsClassNameTimesQuantity',
41
        'TableID' => 'The main definition on which a lot of others are based. Use in the following context: Order.AjaxDefinitions.TableID OR OrderModifier.AjaxDefinitions.TableID OR OrderItem.AjaxDefinitions.TableID',
42
        'TableTotalID' => 'The total cost. Use in the following context: Order.AjaxDefinitions.TableTotalID OR OrderModifier.AjaxDefinitions.TableTotalID OR OrderItem.AjaxDefinitions.TableTotalID',
43
        'HiddenPageTitleID' => 'The ID used to identify a (hidden) element that contains the title of the page. This can be used for ajax updates of the product list.  It will be used to update the title of the page. For example, we can change the PageTitle to MyPage - sorted by Price.',
44
        'ProductListHolderID' => 'The ID used to identify the product group list holder.  This list can be replaced using ajax. ',
45
        'ProductListAjaxifiedLinkClassName' => 'The class name use for sections that contain links for showing alternative views of the product group list. ',
46
        'ProductListItemClassName' => 'The class used to identify each LI item in the list of product items on the product group page (or elsewhere).',
47
        'ProductListItemInCartClassName' => 'The class used to identify the product actions of each LI list item of the list of products that is in the cart right now.',
48
        'ProductListItemNotInCartClassName' => 'The class used to identify each LI item of the list of products that is NOT in the cart right now.',
49
        'TableMessageID' => 'The cart message (e.g. product added). Use in the following context: Order.AjaxDefinitions.TableMessageID',
50
        'TableSubTotalID' => 'The sub-total for the order. Use in the following context: Order.AjaxDefinitions.TableMessageID',
51
        'ExpectedCountryClassName' => 'The holder of the expected country name. Use in the following context: AjaxDefinitions.ExpectedCountryClassName',
52
        'CountryFieldID' => 'The field used for selecting the country. Use in the following context: AjaxDefinitions.CountryFieldID',
53
        'RegionFieldID' => 'The field used for selecting the region. Use in the following context: AjaxDefinitions.RegionFieldID',
54
        'TableTitleID' => 'The title for the item in the checkout page. Use in the following context: OrderItem.AjaxDefinitions.TableTitleID OR OrderModifier.AjaxDefinitions.TableTitleID',
55
        'CartTitleID' => 'The title for the item in the cart (not on the checkout page). Use in the following context: OrderItem.AjaxDefinitions.CartTitleID OR OrderModifier.AjaxDefinitions.CartTitleID',
56
        'TableSubTitleID' => 'The sub-title for the item in the checkout page. Use in the following context: OrderItem.AjaxDefinitions.TableSubTitleID OR OrderModifier.AjaxDefinitions.TableSubTitleID ',
57
        'CartSubTitleID' => 'The sub-title for the item in the cart (not on the checkout page). Use in the following context: OrderItem.AjaxDefinitions.CartSubTitleID OR OrderModifier.AjaxDefinitions.CartSubTitleID ',
58
        'QuantityFieldName' => 'The quantity field for the order item. Use in the following context: OrderItem.AjaxDefinitions.QuantityFieldName',
59
        'UniqueIdentifier' => 'Unique identifier for the buyable (product). Use in the following context: Buyable.AjaxDefinitions.UniqueIdentifier',
60
    );
61
62
    /**
63
     * returns defition of Ajax Method.
64
     *
65
     * @param string $name
66
     *
67
     * @return string
68
     */
69
    public function getAjaxMethod($name)
70
    {
71
        return $this->ajaxMethods[$name];
72
    }
73
74
    /**
75
     * returns the definition of an ajax definition.
76
     *
77
     * @return array
78
     */
79
    public function getAjaxMethods($name = '')
0 ignored issues
show
The parameter $name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
80
    {
81
        return $this->ajaxMethods;
82
    }
83
84
    /**
85
     * Tells us the svn revision of e-commerce in use.
86
     *
87
     * @return int
88
     */
89
    public function SvnVersion()
90
    {
91
        $svnrev = '0';
92
        $file = Director::baseFolder().'/ecommerce/.svn/entries';
93
        if (file_exists($file)) {
94
            $svn = @File($file);
95
            if ($svn && isset($svn[3])) {
96
                $svnrev = $svn[3];
97
            }
98
        }
99
100
        return $svnrev;
101
    }
102
103
    private $definitionGrouping = array(
104
        'GENERAL AND CMS CONFIG' => array(
105
            'EcommerceDBConfig',
106
            'SiteConfig',
107
            'StoreAdmin',
108
            'ProductsAndGroupsModelAdmin',
109
            'ProductConfigModelAdmin',
110
            'SalesAdmin',
111
        ),
112
        'TEMPLATES' => array(
113
            'Templates',
114
            'EcommerceConfigAjax',
115
        ),
116
        'PRODUCTS' => array(
117
            'ProductGroup',
118
            'Product_Image',
119
            'ProductSearchForm',
120
        ),
121
        'ORDER OBJECTS' => array(
122
            'Order',
123
            'OrderItem',
124
            'OrderModifier',
125
        ),
126
        'CART' => array(
127
            'ShoppingCart',
128
            'ShoppingCart_Controller',
129
            'CartResponse',
130
        ),
131
        'CHECKOUT' => array(
132
            'Pages',
133
            'CartPage_Controller',
134
            'CheckoutPage_Controller',
135
            'ShopAccountForm_Validator',
136
            'OrderModifierForm',
137
            'EcommercePaymentController',
138
            'OrderFormAddress'
139
        ),
140
        'POST SALE PROCESSING' => array(
141
            'OrderConfirmationPage_Controller',
142
            'OrderStep',
143
            'OrderStep_Confirmed',
144
            'OrderStatusLog',
145
            'OrderStatusLogForm',
146
            'Email',
147
            'Order_Email',
148
        ),
149
        'CUSTOMERS' => array(
150
            'OrderAddress',
151
            'EcommerceRole',
152
            'BillingAddress',
153
            'ShippingAddress',
154
            'EcommerceCountry',
155
            'EcommerceRegion',
156
        ),
157
        'PAYMENT AND MONEY' => array(
158
            'EcommerceCurrency',
159
            'EcommerceMoney',
160
            'EcommercePayment',
161
            'ExpiryDateField',
162
        ),
163
        'CLEANUP AND OTHER TASKS' => array(
164
            'EcommerceTaskCartCleanup',
165
        ),
166
    );
167
168
    /**
169
     * @return array
170
     */
171
    public function GroupDefinitions()
172
    {
173
        return $this->definitionGrouping + array('OTHER' => array());
174
    }
175
176
    /**
177
     * Get a list of all definitions required for e-commerce.
178
     * We have this here so that we can check that all static variables have been defined.
179
     * We can also use this list for clean formatting.
180
     *
181
     * This list is for developers only
182
     *
183
     * @param string $className - only return for this class name
184
     * @param string #variable - only return this variable (must define class name as well)
185
     *
186
     * @return array | String
187
     */
188
    public function Definitions($className = '', $variable = '')
189
    {
190
        $array = array(
191
192
        ################### GENERAL AND CMS CONFIG #####################
193
            'EcommerceDBConfig' => array(
194
                'ecommerce_db_config_class_name' => 'Class Name for the DataObject that contains the settings for the e-commerce application',
195
                'array_of_buyables' => "Array of classes (e.g. Product, ProductVariation, etc...) that are buyable.  You do not need to include a class that extends a buyable.  For example, if you create a class called 'MyProduct' extending Product then you do not need to list it here.",
196
            ),
197
            'EcommerceConfigAjax' => array(
198
                'definitions_class_name' => 'Class Name (string) for the class used to define and name all the ajax IDs and Classes.',
199
                'cart_js_file_location' => 'The location for the EcomCart.js (javascipt that runs the cart) file.  The default one is ecommerce/javascript/EcomCart.js',
200
                'dialogue_js_file_location' => 'The location for the dialogue (pop-up) javascript.  E-commerce comes with it a default <i>Simple Dialogue</i> pop-up dialogue, but you can also use your own (e.g. prettyPhoto or Greybox).',
201
            ),
202
            'StoreAdmin' => array(
203
                'managed_models' => "An array of data object classes that are managed as 'Store' configuration items.  This configuration is used a lot to add extra menu items. ",
204
            ),
205
            'ProductsAndGroupsModelAdmin' => array(
206
                'managed_models' => 'An array of data object classes that are managed as Products and Product Groups ',
207
            ),
208
            'ProductConfigModelAdmin' => array(
209
                'managed_models' => "An array of data object classes that are managed as 'Product Config' configuration items.  These are all items that relate to Products and Product Groups that are not in the main group.  This includes any searches carried out in the Product Group. ",
210
            ),
211
            'SalesAdmin' => array(
212
                'managed_models' => "An array of data object classes that are managed as 'Store' configuration items.  This configuration is used a lot to add extra menu items. ",
213
            ),
214
215
        ################### PRODUCT DISPLAY #####################
216
            'ProductGroup' => array(
217
                'base_buyable_class' => 'The base class for the products being retrieved.  Usually this is Product, but it can also be MyProduct or MyProductAsDataObject or anything else that implements the Buyable Interface.',
218
                'actively_check_for_can_purchase' => 'Before listing a product, actively check if canPurcahse returns true.  This is useful, when for example, you are deciding whether or not products can be sold based on the country of the customer.',
219
                'maximum_number_of_products_to_list' => 'The maximum number of products to be shown in a list.  For performance reasons, we suggest you limit this to 1000 for big sites and as low as 200 for small servers.',
220
                'sort_options' => "associative sort options array with sub-keys of Title and SQL, e.g. 'default' = array('Title' => 'default', 'SQL' => 'Title DESC')",
221
                'filter_options' => "associative filters options array with sub-keys of Title and SQL, e.g. 'default' = array('Title' => 'Featured', 'SQL' => 'Featured = 1')",
222
                'display_styles' => "associative display styles array with its key as template name, e.g. 'MyTemplateName' => 'Full Details'",
223
                'session_name_for_product_array' => 'This is the name for variable stored in session.  The variable stores a list of IDs for products being shown on the product group.  We store this so that we can go previous and next for each product. ',
224
            ),
225
            'ProductGroupSearchPage' => [
226
                'best_match_key' => 'Sort key used to sort by relevance.',
227
                'sort_options' => "Additional associative sort options array with sub-keys of Title and SQL, e.g. 'default' = array('Title' => 'default', 'SQL' => 'Title DESC') for searching. Include on with the best_match_key.",
228
                'maximum_number_of_products_to_list_for_search' => "Maximum number of products returned in search.",
229
            ],
230
            'Product' => array(
231
                'folder_name_for_images' => 'Default folder for uploading product images.',
232
                'add_data_to_meta_description_for_search' => 'Add a bunch of text to the MetaDescription Field so that the FullText Search can find more details',
233
            ),
234
            'Product_Image' => array(
235
                'thumbnail_width' => 'Thumbnail width in pixels. For thumbnails, we use paddedResize.',
236
                'thumbnail_height' => 'Thumbnail height in pixels. For thumbnails, we use paddedResize.',
237
                'small_image_width' => 'Width for the small image (this is usually the product group image). We use these settings to improve image quality and to set strict standard sizes.  For the thumbnail and small image we set both height and width. For the content and large image we use the SetWidth method.',
238
                'small_image_height' => 'Height for the small image (this is usually the product group image). We use these settings to improve image quality and to set strict standard sizes.  For the thumbnail and small image we set both height and width. For the content and large image we use the SetWidth method.',
239
                'content_image_width' => 'Width for the content image. We use these settings to improve image quality and to set strict standard sizes. For the thumbnail and small image we set both height and width. For the content and large image we use the SetWidth method.',
240
                'large_image_width' => 'Width for the large (zoom) image. We use these settings to improve image quality and to set strict standard sizes.  For the thumbnail and small image we set both height and width. For the content and large image we use the SetWidth method.',
241
            ),
242
            'ProductSearchForm' => array(
243
                'include_price_filters' => 'For the product search form, make sure that there are no filter fields for minimum and maximum price',
244
                'form_data_session_variable' => 'Name of the session variable used to store the form field values',
245
                'product_session_variable' => 'Name of a session variable used to tell the website what products - based on a search - are to be shown',
246
                'product_group_session_variable' => 'Name of the session variable used to tell the website what products GROUPS - based on a search - are to be shown',
247
            ),
248
249
        ################### CART AND CHECKOUT PROCESS #####################
250
            'ShoppingCart' => array(
251
                'session_code' => 'The code use for the session variable that stores the Order ID.',
252
                'cleanup_every_time' => 'Are carts are cleaned up all the time (if this is set to FALSE then we recommend you setup a cron job to clean old carts - this is recommended on large sites where any run-time activity will slow the site down (it is more efficient to clear 1000 carts once an hour than to clear 1 cart ever second))?',
253
                'default_param_filters' => 'Advanced filtering in the shopping cart.  Not currently being used. ',
254
                'response_class' => 'Class used for ajax responses.',
255
            ),
256
            'ShoppingCart_Controller' => array(
257
                'url_segment' => 'URL Segment used for the shopping cart.',
258
            ),
259
            'CartResponse' => array(
260
                'cart_responses_required' => 'An array of the cart responses required for AJAX.  This array also identifies the unique IDs used in the html that will be updated by the ajax response.',
261
            ),
262
            'CartPage_Controller' => array(
263
                'session_code' => 'Code name for session variable used in Cart Page.  This session variable is used to retain a message.',
264
            ),
265
            'CheckoutPage_Controller' => array(
266
                'checkout_steps' => 'The Checkout Steps.  This can be defined as you like, but the last step should always be: orderconfirmationandpayment.',
267
                'ajaxify_steps' => 'Array of Javascript files that are required to ajaxify the steps in the checkout. Defaults to none, but there is a sample JS file available: ecommerce/javascript/EcomCheckoutPage.js.',
268
            ),
269
            'ShopAccountForm_Validator' => array(
270
                'minimum_password_length' => 'The minimum length of the password for an account.',
271
            ),
272
            'OrderModifierForm' => array(
273
                'controller_class' => 'The controller class is used for Order Modifier Forms.',
274
                'validator_class' => 'The validator class is used for Order Modifier Forms.',
275
            ),
276
            'EcommercePaymentController' => array(
277
                'url_segment' => 'URL Segment used for the payment process.',
278
            ),
279
280
            'OrderFormAddress' => array(
281
                'shipping_address_first' => 'Show the shipping address before the billing address. This is a better option if it is likely that you have a billing address that is not the same as the shipping address.'
282
            ),
283
284
        ################### POST SALE PROCESSING #####################
285
            'OrderConfirmationPage_Controller' => array(
286
                'include_as_checkout_step' => 'Include the order confirmation as one of the checkout steps, visually, in the list of steps shown.',
287
                'google_analytics_variable' => 'The name of the Google Analytics variables (usually ga or _gaq).'
288
            ),
289
            'OrderStep' => array(
290
                'order_steps_to_include' => 'Another very important definition.  These are the steps that the order goes through from creation to archiving.  A bunch of standard steps have been included in the e-commerce module, but this is also a place where you can add / remove your own customisations (steps) as required by your individual project.',
291
                'number_of_days_to_send_update_email' => 'The maximum number of days available to send an status update for the customer for the specific order step',
292
            ),
293
            'OrderStep_Confirmed' => array(
294
                'list_of_things_to_check' => 'One of the steps in the order steps sequence is the Order Confirmation.  This is when the Shop Admin looks at all the detail in the order and confirms it is ready to be completed.  Here you can create an HTML list of items to check (e.g. has it been paid, do you have the products in stock, is there a delivery address, etc....)',
295
            ),
296
            'OrderStatusLog' => array(
297
                'available_log_classes_array' => 'Tells us what order log classes are to be used. OrderStatusLog_Submitted should always be used and does not need to be listed here.',
298
                'order_status_log_class_used_for_submitting_order' => 'This is the log class used to record the submission of the order.  It is crucial to set this to the right log class, as a lot of the functionality in e-commerce depends on it: ',
299
            ),
300
            'OrderStatusLogForm' => array(
301
                'controller_class' => 'The controller class is used for OrderStatusLogForm forms.',
302
                'validator_class' => 'The validator class is used for OrderStatusLogForm forms.',
303
            ),
304
            'Order_Email' => array(
305
                'send_all_emails_plain' => 'Should all the emails be send as plain text?  Not recommended.',
306
                'css_file_location' => "This is a really useful setting where you can specify the location for a css file that is 'injected' into the customer emails. ",
307
                'copy_to_admin_for_all_emails' => 'Send a copy to the shop administrator for every email sent?',
308
            ),
309
310
        ################### ORDER DETAILS #####################
311
            'Order' => array(
312
                'modifiers' => 'This is the single most important setting.  here you determine what modifiers are being added to every order.  You can just add them as a non-associative array.  However, their order is important!',
313
                'minutes_an_order_can_be_viewed_without_logging_in' => "Orders can be viewed with the special retrieve link (without the need for the user to log in) for xxx number of minutes.",
314
                'maximum_ignorable_sales_payments_difference' => "The maximum allowable difference between the Order Total and the Payment Total. 	If this value is, for example, 10 cents and the total amount outstanding for an order is less than ten cents, than the order is considered 'paid'",
315
                'order_id_start_number' => 'The starting number for the order number. For example, if you enter 1000 here then the first order will have number 1000, the next one 1001 and so on.',
316
                'template_id_prefix' => 'If you end up with conflicts in your templates (e.g. having the same ID twice) then you can use this variable to set an prefix to all PHP generated IDs in all templates. We use these PHP generated IDs for AJAX templates - where HTML, JS and PHP need to work together.',
317
                'ajax_subtotal_format' => 'This is used when AJAX returns some values to update on the checkout page. Specify which function returns the SubTotal value. You can also specify if you want a format to be called on that function.',
318
                'ajax_total_format' => 'This is used when AJAX returns some values to update on the checkout page. Specify which function returns the Total value. You can also specify if you want a format to be called on that function.',
319
                'date_format_for_title' => 'PHP Date format to show date in the title of the order e.g. Y-m-d, leave blank to exclude date format.',
320
                'include_customer_name_in_title' => 'Include the name of the customer in the title of the order.  Set to false to exclude the name of the customer in the order title.',
321
            ),
322
            'OrderItem' => array(
323
                'ajax_total_format' => 'This is used when AJAX returns some values to update on the checkout page. Specify which function returns the Total value. You can also specify if you want a format to be called on that function.',
324
            ),
325
            'OrderModifier' => array(
326
                'ajax_total_format' => 'This is used when AJAX returns some values to update on the checkout page. Specify which function returns the Total value. You can also specify if you want a format to be called on that function.',
327
            ),
328
329
        ################### CUSTOMERS #####################
330
            'OrderAddress' => array(
331
                'use_separate_shipping_address' => 'Do the goods need to get shipped and if so, do we allow these goods to be shipped to a different address than the billing address?',
332
                'use_shipping_address_for_main_region_and_country' => 'In determing the country/region from which the order originated. For, for example, tax purposes - we use the Billing Address (@see Order::Country). However, we can also choose the Shipping Address by setting this variable to TRUE.',
333
                'field_class_and_id_prefix' => 'In case you have some conflicts in the class / IDs for formfields then you can use this variable to add a few characters in front of the classes / IDs',
334
            ),
335
            'EcommerceRole' => array(
336
                'permission_category' => 'E-commerce permission group name.',
337
                'allow_customers_to_setup_accounts' => "Allow customers to become members when they purchase items. If this is false then customers can never setup an account. Orders will still get a member assigned to them but the member does not log in and they are not prompted for a password.",
338
                'must_have_account_to_purchase' => 'When this is set to TRUE, any purchasers must log in or create an account. When set to false, customers still get added as a member, but they can purchase without logging in or choosing a password.',
339
                'automatically_update_member_details' => 'When set to true, the member fields (e.g. email, surname, first name) will be automatically updated from the billing address.  That is, if the customers enters a different email or surname in the billing field then the member record will be updated based on these new values.',
340
                'customer_group_code' => 'Code for the customer member group.',
341
                'customer_group_name' => 'Title (name) for the customer member group.',
342
                'customer_permission_code' => 'Permission code for the customer member group.',
343
                'admin_group_code' => 'Code for the shop administrator member group.',
344
                'admin_group_name' => 'Title (name) for the shop administrator member group.',
345
                'admin_group_user_first_name' => 'First name for the shop administrator (e.g. John).',
346
                'admin_group_user_surname' => 'Last name for the shop administrator (e.g. Smith).',
347
                'admin_group_user_email' => 'Email address for the shop administrator (e.g. [email protected]).',
348
                'admin_permission_code' => 'Permission code for the shop administrator member group.',
349
                'admin_role_title' => 'Role title for the shop administrator member group.',
350
                'admin_role_permission_codes' => 'Permission codes for the shop administrator member group.',
351
                'assistant_group_code' => 'Code for the shop assistant member group.',
352
                'assistant_group_name' => 'Title (name) for the shop assistant member group.',
353
                'assistant_group_user_first_name' => 'First name for the shop assistant (e.g. John).',
354
                'assistant_group_user_surname' => 'Last name for the shop assistant (e.g. Smith).',
355
                'assistant_group_user_email' => 'Email address for the shop assistant (e.g. [email protected]).',
356
                'assistant_permission_code' => 'Permission code for the shop assistant member group.',
357
                'assistant_role_title' => 'Role title for the shop assistant member group.',
358
                'assistant_role_permission_codes' => 'Permission codes for the shop assistant member group.',
359
                'process_orders_permission_code' => 'Permission code for being allowed to process orders. This code is separate from admins and assistants to make it easier to apply separate codes to groups.'
360
            ),
361
            'BillingAddress' => array(
362
                'allow_selection_of_previous_addresses_in_checkout' => 'In the checkout, allow a customer to select from previously used addresses.',
363
                'required_fields' => 'List of fields that is required to be entered.',
364
                'fields_to_google_geocode_conversion' => 'This variable tells us how Billing Fields map to the Google Geo Coding objects.  If you set it to null or an empty array then there will be no geocoding. See https://developers.google.com/maps/documentation/geocoding/#Types for more information.',
365
            ),
366
            'ShippingAddress' => array(
367
                'allow_selection_of_previous_addresses_in_checkout' => 'In the checkout, allow a customer to select from previously used addresses.',
368
                'required_fields' => 'List of fields that is required to be entered.',
369
                'fields_to_google_geocode_conversion' => 'This variable tells us how Shipping Fields map to the Google Geo Coding objects.  If you set it to null or an empty array then there will be no geocoding. See https://developers.google.com/maps/documentation/geocoding/#Types for more information.',
370
            ),
371
            'EcommerceCountry' => array(
372
                'allowed_country_codes' => 'To what countries are you selling?  You can leave this as an empty array, in case you are selling to all countries or you can restrict it to just one country or a handful.  Once set, you can adjust this list in EcommerceCountry using the CMS. ',
373
                'visitor_country_provider' => 'The class that is being used to provide the country of the customer. Usually this is GEOIP, but you can also setup your own one. This class just needs one public method: getCountry.',
374
                'default_country_code' => 'The default country code (e.g. NZ or CA or UK). ',
375
            ),
376
            'EcommerceRegion' => array(
377
                'visitor_region_provider' => 'The class that is being used to provide the region of the customer. It is sort of like a GEOIP for regions.',
378
                'show_freetext_region_field' => "Provide a free text region field if no regions are specified. Region can also be 'State', or 'Province', etc...",
379
            ),
380
381
        ################### PAYMENT AND MONEY #####################
382
            'EcommerceCurrency' => array(
383
                'default_currency' => 'The default currency used on the site.',
384
                'exchange_provider_class' => 'The name of the class used to provide currency exchange rate.... You can easily built your own class here that can either provide fixed rates, database stored rates or dynamic rates.',
385
            ),
386
            'EcommerceMoney' => array(
387
                'default_format' => 'Here you specify which function you want to be called as the default format for a Money object on the all site.',
388
            ),
389
            'EcommercePayment' => array(
390
                'supported_methods' => 'Associative array of payment methods, e.g. ChequePayment: pay by cheque, CreditCardPayment: pay by credit card, etc....',
391
            ),
392
            'ExpiryDateField' => array(
393
                'short_months' => 'Should we use short codes for the Expiry Date Field (e.g. Jan rather than January)?',
394
            ),
395
396
        ################### CLEANUP AND OTHER TASKS #####################
397
            'EcommerceTaskCartCleanup' => array(
398
                'clear_minutes' => 'The number of minutes after which carts are considered abandonned. If set to zero, all objects will be cleared. If set to ten, objects older than ten minutes will be cleared.',
399
                'clear_minutes_empty_carts' => 'The number of minutes after which empty carts should be deleted (to reduce the amount of empty (meaningless) carts in the database). If set to zero, all objects will be cleared. If set to ten, objects older than ten minutes will be cleared.',
400
                'maximum_number_of_objects_deleted' => 'This sets the total number of objects to be cleaned per clean.  We can keep this low to reduce time per clean and to reduce risks.',
401
                'never_delete_if_linked_to_member' => 'If set to TRUE, then orders with a member linked to it will never be deleted.',
402
                'one_to_one_classes' => 'An array of key / value pairs that are linked to orders as one-to-one relationships.  The key is the order field name (e.g. BillingAddressID) and the value is the class name (e.g. BillingAddress)',
403
                'one_to_many_classes' => 'An array of key / value pairs that are linked to orders as one-to-many relationships.  The key is the class with the order ID and the value is the class name with the LastEdited field.',
404
                'many_to_many_classes' => 'An array of key / value pairs that are linked to orders as many-to-many relationships.  Currently not in use.',
405
            ),
406
        );
407
        //add more stuff through extensions
408
409
        $extendedArray = $this->extend('moreDefinitions', $array);
410
        if ($extendedArray !== null && is_array($extendedArray) && count($extendedArray)) {
411
            foreach ($extendedArray as $extendedLabelsUpdate) {
412
                $array = array_merge($array, $extendedLabelsUpdate);
413
            }
414
        }
415
        //add more stuff through child classes
416
        $childClasses = ClassInfo::subclassesFor($this->class);
417
        if (is_array($childClasses) && count($childClasses)) {
418
            foreach ($childClasses as $class) {
419
                if ($class != $this->class) {
420
                    $childObject = new $class();
421
                    $array = array_merge($array, $childObject->Definitions());
422
                }
423
            }
424
        }
425
        //return what is appropriate
426
        if ($className && $variable) {
427
            return $array[$className][$variable];
428
        } elseif ($className) {
429
            return $array[$className];
430
        } else {
431
            return $array;
432
        }
433
    }
434
}
435