Source of file EcommerceRegion.php
Size: 11,547 Bytes - Last Modified: 2021-12-23T10:39:35+00:00
/var/www/docs.ssmods.com/process/src/src/Model/Address/EcommerceRegion.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 | <?php namespace Sunnysideup\Ecommerce\Model\Address; use SilverStripe\Core\Config\Config; use SilverStripe\Forms\FieldList; use SilverStripe\ORM\DataObject; use Sunnysideup\CmsEditLinkField\Api\CMSEditLinkAPI; use Sunnysideup\Ecommerce\Api\ShoppingCart; use Sunnysideup\Ecommerce\Config\EcommerceConfig; use Sunnysideup\Ecommerce\Dev\EcommerceCodeFilter; use Sunnysideup\Ecommerce\Interfaces\EditableEcommerceObject; /** * @description: This class helps you to manage regions within the context of e-commerce. * The regions can be states (e.g. we only sell within New York and Penn State), suburbs (pizza delivery place), * or whatever other geographical borders you are using. * Each region has one country, so a region can not span more than one country. * * @authors: Nicolaas [at] Sunny Side Up .co.nz * @package: ecommerce * @sub-package: address */ class EcommerceRegion extends DataObject implements EditableEcommerceObject { /** * these variables and methods allow to to "dynamically limit the regions available, based on, for example: ordermodifiers, item selection, etc.... * for example, if hot delivery of a catering item is only available in a certain region, then the regions can be limited with the methods below. * NOTE: these methods / variables below are IMPORTANT, because they allow the dropdown for the region to be limited for just that order. * * @var array of regions codes, e.g. ("NSW", "WA", "VIC"); */ protected static $_for_current_order_only_show_regions = []; /** * what variables are accessible through http://mysite.com/api/ecommerce/v1/EcommerceRegion/. * * @var array */ private static $api_access = [ 'view' => [ 'Code', 'Name', ], ]; /** * @var string */ private static $visitor_region_provider = 'EcommerceRegion_VisitorRegionProvider'; /** * @var bool */ private static $show_freetext_region_field = true; /** * standard SS variable. * * @var string */ private static $table_name = 'EcommerceRegion'; private static $db = [ 'Code' => 'Varchar(20)', 'Name' => 'Varchar(200)', 'DoNotAllowSales' => 'Boolean', 'IsDefault' => 'Boolean', ]; /** * standard SS variable. * * @var array */ private static $has_one = [ 'Country' => EcommerceCountry::class, ]; /** * standard SS variable. * * @var array */ private static $indexes = [ 'Name' => true, 'Code' => true, 'DoNotAllowSales' => true, ]; /** * standard SS variable. * * @var array */ private static $default_sort = [ 'Name' => 'ASC', 'ID' => 'ASC', ]; /** * standard SS variable. * * @var string */ private static $singular_name = 'Region'; /** * standard SS variable. * * @var string */ private static $plural_name = 'Regions'; /** * standard SS variable. * * @var array */ private static $searchable_fields = [ 'Name' => 'PartialMatchFilter', 'Code' => 'PartialMatchFilter', ]; /** * standard SS variable. * * @var array */ private static $field_labels = [ 'Name' => 'Region', ]; /** * standard SS variable. * * @var array */ private static $summary_fields = [ 'Name' => 'Name', 'Country.Title' => 'Country', ]; /** * Standard SS variable. * * @var string */ private static $description = 'A region within a country. This can be a state or a province or the equivalent.'; /** * @var array */ private static $_for_current_order_do_not_show_regions = []; public function i18n_singular_name() { return _t('EcommerceRegion.REGION', 'Region'); } public function i18n_plural_name() { return _t('EcommerceRegion.REGIONS', 'Regions'); } /** * do we use regions at all in this ecommerce application? * * @return bool */ public static function show() { if (Config::inst()->get(EcommerceRegion::class, 'show_freetext_region_field')) { return true; } return (bool) EcommerceRegion::get()->exists(); } /** * Standard SS FieldList. * * @return \SilverStripe\Forms\FieldList */ public function getCMSFields() { $fields = parent::getCMSFields(); $fields->removeByName('CountryID'); return $fields; } /** * link to edit the record. * * @param null|string $action - e.g. edit * * @return string */ public function CMSEditLink($action = null) { return CMSEditLinkAPI::find_edit_link_for_object($this, $action); } /** * checks if a code is allowed. * * @param string $code - e.g. NZ, NSW, or CO * * @return bool */ public static function code_allowed($code) { $region = DataObject::get_one( EcommerceRegion::class, ['Code' => $code] ); if ($region) { return self::regionid_allowed($region->ID); } return false; } /** * checks if a code is allowed. * * @param string $regionID - e.g. NZ, NSW, or CO * * @return bool */ public static function regionid_allowed($regionID) { return array_key_exists($regionID, self::list_of_allowed_entries_for_dropdown()); } /** * converts a code into a proper title. * * @param int $regionID (Code) * * @return string ( name) */ public static function find_title($regionID) { $options = self::get_default_array(); // check if code was provided, and is found in the country array if ($options && isset($options[$regionID])) { return $options[$regionID]; } return ''; } // DYNAMIC LIMITS..... /** * takes the defaultArray and limits it with "only show" and "do not show" value, relevant for the current order. * * @return array (Code, Title) */ public static function list_of_allowed_entries_for_dropdown() { $defaultArray = self::get_default_array(); $onlyShow = self::get_for_current_order_only_show_regions(); $doNotShow = self::get_for_current_order_do_not_show_regions(); if (is_array($onlyShow) && count($onlyShow)) { foreach (array_keys($defaultArray) as $id) { if (! in_array($id, $onlyShow, true)) { unset($defaultArray[$id]); } } } if (is_array($doNotShow) && count($doNotShow)) { foreach ($doNotShow as $id) { if (isset($defaultArray[$id])) { unset($defaultArray[$id]); } } } return $defaultArray; } /** * @param int $orderID * * @return array */ public static function get_for_current_order_only_show_regions(?int $orderID = 0) { $orderID = ShoppingCart::current_order_id($orderID); return isset(self::$_for_current_order_only_show_regions[$orderID]) ? self::$_for_current_order_only_show_regions[$orderID] : []; } /** * merges arrays... * * @param int $orderID */ public static function set_for_current_order_only_show_regions(array $a, $orderID = 0) { //We MERGE here because several modifiers may limit the countries $previousArray = self::get_for_current_order_only_show_regions($orderID); self::$_for_current_order_only_show_regions[$orderID] = array_intersect($a, $previousArray); } /** * @param int $orderID * * @return array */ public static function get_for_current_order_do_not_show_regions(?int $orderID = 0) { $orderID = ShoppingCart::current_order_id($orderID); return isset(self::$_for_current_order_do_not_show_regions[$orderID]) ? self::$_for_current_order_do_not_show_regions[$orderID] : []; } /** * merges arrays... * * @param int $orderID */ public static function set_for_current_order_do_not_show_regions(array $a, $orderID = 0) { //We MERGE here because several modifiers may limit the countries $previousArray = self::get_for_current_order_do_not_show_regions($orderID); self::$_for_current_order_do_not_show_regions[$orderID] = array_merge($a, $previousArray); } /** * This function works out the most likely region for the current order. * * @return int */ public static function get_region_id() { $regionID = 0; $order = ShoppingCart::current_order(); if ($order) { $region = $order->Region(); if ($region) { $regionID = $region->ID; } } //3. check GEOIP information if (! $regionID) { $regions = EcommerceRegion::get()->filter(['IsDefault' => 1]); if ($regions) { $regionArray = self::list_of_allowed_entries_for_dropdown(); foreach ($regions as $region) { if (in_array($region->ID, $regionArray, true)) { return $region->ID; } } } if (is_array($regionArray) && count($regionArray)) { $regionID = array_key_first($regionArray); } } return $regionID; } /** * returns the country based on the Visitor Country Provider. * this is some sort of IP recogniser system (e.g. Geoip Class). * * @return int */ public static function get_region_from_ip() { $visitorCountryProviderClassName = EcommerceConfig::get(EcommerceCountry::class, 'visitor_region_provider'); if (! $visitorCountryProviderClassName) { $visitorCountryProviderClassName = EcommerceRegionVisitorRegionProvider::class; } $visitorCountryProvider = new $visitorCountryProviderClassName(); return $visitorCountryProvider->getRegion(); } /** * @alias for get_region_id */ public static function get_region() { return self::get_region_id(); } /** * standard SS method * cleans up codes. */ protected function onBeforeWrite() { parent::onBeforeWrite(); $filter = EcommerceCodeFilter::create(); $filter->checkCode($this); } /** * This function returns back the default list of regions, filtered by the currently selected country. * * @return array - array of Region.ID => Region.Name */ protected static function get_default_array() { $defaultArray = []; $regions = EcommerceRegion::get() ->Exclude(['DoNotAllowSales' => 1]) ; $defaultRegion = EcommerceCountry::get_country_id(); if ($defaultRegion) { $regions = $regions->Filter(['CountryID' => EcommerceCountry::get_country_id()]); } if ($regions && $regions->exists()) { foreach ($regions as $region) { $defaultArray[$region->ID] = $region->Name; } } return $defaultArray; } } |