public function getSettingsHTML($params = array())
 {
     $values = $this->getSettings();
     if (!empty($params['value'])) {
         $values = array_merge($values, $params['value']);
     }
     $view = wa()->getView();
     $cm = new waCountryModel();
     $view->assign('countires', $cm->all());
     if (!empty($values['country'])) {
         $rm = new waRegionModel();
         $view->assign('regions', $rm->getByCountry($values['country']));
     }
     $namespace = '';
     if (!empty($params['namespace'])) {
         if (is_array($params['namespace'])) {
             $namespace = array_shift($params['namespace']);
             while (($namspace_chunk = array_shift($params['namespace'])) !== null) {
                 $namespace .= "[{$namspace_chunk}]";
             }
         } else {
             $namespace = $params['namespace'];
         }
     }
     $view->assign('namespace', $namespace);
     $view->assign('values', $values);
     $view->assign('p', $this);
     $view->assign('xhr_url', wa()->getAppUrl('webasyst') . '?module=backend&action=regions');
     $html = $view->fetch($this->path . '/templates/settings.html');
     $html .= parent::getSettingsHTML($params);
     return $html;
 }
 public static function settingRegionRatesControl($name, $params = array())
 {
     foreach ($params as $field => $param) {
         if (strpos($field, 'wrapper')) {
             unset($params[$field]);
         }
     }
     if (empty($params['value']) || !is_array($params['value'])) {
         $params['value'] = array();
     }
     $control = '';
     waHtmlControl::addNamespace($params, $name);
     $cm = new waCountryModel();
     $countries = $cm->all();
     $rm = new waRegionModel();
     if ($regions = $rm->getByCountry('rus')) {
         $control .= "<table class=\"zebra\"><thead>";
         $control .= "<tr class=\"gridsheader\"><th colspan=\"3\">";
         $control .= htmlentities('Распределите регионы по тарифным поясам Почты России', ENT_QUOTES, 'utf-8');
         $control .= "</th>";
         $control .= "<th>Только авиа</th>";
         $control .= "</th></tr></thead><tbody>";
         $params['control_wrapper'] = '<tr><td>%s</td><td>&rarr;</td><td>%s</td><td>%s</td></tr>';
         $params['title_wrapper'] = '%s';
         $params['description_wrapper'] = '%s';
         $params['options'] = array();
         $params['options'][0] = _wp('*** пояс не выбран ***');
         for ($region = 1; $region <= 5; $region++) {
             $params['options'][$region] = sprintf(_wp('Пояс %d'), $region);
         }
         $avia_params = $params;
         $avia_params['control_wrapper'] = '%2$s';
         $avia_params['description_wrapper'] = false;
         $avia_params['title_wrapper'] = false;
         foreach ($regions as $region) {
             $name = 'zone';
             $id = $region['code'];
             if (empty($params['value'][$id])) {
                 $params['value'][$id] = array();
             }
             $params['value'][$id] = array_merge(array($name => 0, 'avia_only' => false), $params['value'][$id]);
             $region_params = $params;
             waHtmlControl::addNamespace($region_params, $id);
             $avia_params = array('namespace' => $region_params['namespace'], 'control_wrapper' => '%2$s', 'description_wrapper' => false, 'title_wrapper' => false, 'value' => $params['value'][$id]['avia_only']);
             $region_params['value'] = max(0, min(5, $params['value'][$id][$name]));
             $region_params['description'] = waHtmlControl::getControl(waHtmlControl::CHECKBOX, 'avia_only', $avia_params);
             $region_params['title'] = $region['name'];
             if ($region['code']) {
                 $region_params['title'] .= " ({$region['code']})";
             }
             $control .= waHtmlControl::getControl(waHtmlControl::SELECT, 'zone', $region_params);
         }
         $control .= "</tbody>";
         $control .= "</table>";
     } else {
         $control .= 'Не определено ни одной области. Для работы модуля необходимо определить хотя бы одну область в России (см. раздел «Страны и области»).';
     }
     return $control;
 }
 /**
  * @see waShipping::getSettingsHTML()
  * @param array $params
  * @return string HTML
  */
 public function getSettingsHTML($params = array())
 {
     $params += array('translate' => array(&$this, '_w'));
     $values = $this->getSettings();
     if (!empty($params['value'])) {
         $values = array_merge($values, $params['value']);
     }
     if (!$values['rate_zone']['country']) {
         $l = substr(wa()->getUser()->getLocale(), 0, 2);
         if ($l == 'ru') {
             $values['rate_zone']['country'] = 'rus';
             $values['rate_zone']['region'] = '77';
             $values['city'] = '';
         } else {
             $values['rate_zone']['country'] = 'usa';
         }
     }
     $view = wa()->getView();
     $cm = new waCountryModel();
     $view->assign('countries', $cm->all());
     if (!empty($values['rate_zone']['country'])) {
         $rm = new waRegionModel();
         $view->assign('regions', $rm->getByCountry($values['rate_zone']['country']));
     }
     if (!empty($values['rate'])) {
         self::sortRates($values['rate']);
         if ($values['rate_by'] == 'price') {
             $values['rate'] = array_reverse($values['rate']);
         }
     } else {
         $values['rate'] = array();
         $values['rate'][] = array('limit' => 0, 'cost' => 0.0);
     }
     $app_config = wa()->getConfig();
     if (method_exists($app_config, 'getCurrencies')) {
         $view->assign('currencies', $app_config->getCurrencies());
     }
     $namespace = '';
     if (!empty($params['namespace'])) {
         if (is_array($params['namespace'])) {
             $namespace = array_shift($params['namespace']);
             while (($namespace_chunk = array_shift($params['namespace'])) !== null) {
                 $namespace .= "[{$namespace_chunk}]";
             }
         } else {
             $namespace = $params['namespace'];
         }
     }
     $view->assign('namespace', $namespace);
     $view->assign('values', $values);
     $view->assign('p', $this);
     $html = '';
     $view->assign('xhr_url', wa()->getAppUrl('webasyst') . '?module=backend&action=regions');
     $view->assign('map_adapters', wa()->getMapAdapters());
     $html .= $view->fetch($this->path . '/templates/settings.html');
     $html .= parent::getSettingsHTML($params);
     return $html;
 }
 public function execute()
 {
     $this->response = array('options' => array(), 'oOrder' => array());
     $country = waRequest::request('country');
     if (!$country) {
         return;
     }
     $rm = new waRegionModel();
     foreach ($rm->getByCountryWithFav($country) as $row) {
         if ($row['name'] === '') {
             $this->response['options'][''] = ' ';
             $this->response['oOrder'][] = '';
         } else {
             $this->response['options'][$row['code']] = $row['name'];
             $this->response['oOrder'][] = $row['code'];
         }
     }
 }
 public function execute()
 {
     $country_iso3 = waRequest::request('country');
     if (!$country_iso3) {
         throw new waException('Country not specified.', 404);
     }
     $regions = array();
     switch ($country_iso3) {
         case '%AL':
             $country = array('name' => _w('All countries'));
             break;
         case '%EU':
             $country = array('name' => _w('All European countries'));
             break;
         case '%RW':
             $country = array('name' => _w('Rest of world'));
             break;
         default:
             // Country
             $cm = new waCountryModel();
             $country = $cm->get($country_iso3);
             if (!$country) {
                 throw new waException('Country not found.', 404);
             }
             // Country regions
             $rm = new waRegionModel();
             foreach ($rm->getByCountry($country_iso3) as $r) {
                 $r['css_class'] = 'highlighted just-added hidden';
                 $r['tax_name'] = '';
                 $r['tax_value'] = '';
                 $r['params'] = array('tax_value_modifier' => '+');
                 $regions[] = $r;
             }
             break;
     }
     $this->view->assign('c', array('css_class' => 'highlighted just-added one_rate', 'name' => $country['name'], 'iso3' => $country_iso3, 'regions' => $regions, 'global_rate' => ''));
 }
    /**
     *
     * Country/region dependent select boxes [+ city input]
     *
     * @param string $name
     * @param array $params
     * @return string
     * @example
     * Sample of params defined in proper settings.php
     *
     *    'region_zone' => array(
     *           'title' => 'Sender region',
     *           'control_type' => waHtmlControl::CUSTOM . ' waShipping::settingRegionZoneControl',
     *           'items' => array(
     *               'country' => array(
     *                       'value' => 'usa',
     *                       'description' => 'Represents the country from which the shipment will be originating'
     *               ),
     *               'region' => array(
     *                       'value' => 'NY',
     *                       'description' => 'Represents the state/province from which the shipment will be originating.<br>Required for printing labels'
     *               ),
     *               'city' => array(
     *                       'value' => 'New York',
     *                       'description' => Enter city name<br>Required for printing labels'
     *               ),
     *       )
     *    ),
     *
     *    If 'city' is not missing, city input box is presented
     *
     */
    public static function settingRegionZoneControl($name, $params = array())
    {
        $html = "";
        $plugin = $params['instance'];
        /**
         * @var waShipping $plugin
         */
        $params['items']['country']['value'] = !empty($params['value']['country']) ? $params['value']['country'] : '';
        $params['items']['region']['value'] = !empty($params['value']['region']) ? $params['value']['region'] : '';
        if (isset($params['items']['city'])) {
            $params['items']['city']['value'] = !empty($params['value']['city']) ? $params['value']['city'] : '';
        }
        // country section
        $cm = new waCountryModel();
        $html .= "<div class='country'>";
        $html .= "<select name='{$name}[country]'><option value=''></option>";
        foreach ($cm->all() as $country) {
            $html .= "<option value='{$country['iso3letter']}'" . ($params['items']['country']['value'] == $country['iso3letter'] ? " selected='selected'" : "") . ">{$country['name']}</value>";
        }
        $html .= "</select><br>";
        $html .= "<span class='hint'>{$params['items']['country']['description']}</span></div><br>";
        $regions = array();
        if ($params['items']['country']['value']) {
            $rm = new waRegionModel();
            $regions = $rm->getByCountry($params['items']['country']['value']);
        }
        // region section
        $html .= '<div class="region">';
        $html .= '<i class="icon16 loading" style="display:none; margin-left: -23px;"></i>';
        $html .= '<div class="empty"' . (!empty($regions) ? 'style="display:none;"' : '') . '><p class="small">' . $plugin->_w("Shipping will be restricted to the selected country") . "</p>";
        $html .= "<input name='{$name}[region]' value='' type='hidden'" . (!empty($regions) ? 'disabled="disabled"' : '') . '></div>';
        $html .= '<div class="not-empty" ' . (empty($regions) ? 'style="display:none;"' : '') . ">";
        $html .= "<select name='{$name}[region]'" . (empty($regions) ? 'disabled="disabled"' : '') . '><option value=""></option>';
        foreach ($regions as $region) {
            $html .= "<option value='{$region['code']}'" . ($params['items']['region']['value'] == $region['code'] ? ' selected="selected"' : "") . ">{$region['name']}</option>";
        }
        $html .= "</select><br>";
        $html .= "<span class='hint'>{$params['items']['region']['description']}</span></div><br>";
        // city section
        if (isset($params['items']['city'])) {
            $html .= "<div class='city'>";
            $html .= "<input name='{$name}[city]' value='" . (!empty($params['items']['city']['value']) ? $params['items']['city']['value'] : "") . "' type='text'>\n                <br>";
            $html .= "<span class='hint'>{$params['items']['city']['description']}</span></div>";
        }
        $html .= "</div>";
        $url = wa()->getAppUrl('webasyst') . '?module=backend&action=regions';
        // container id for interaction with js purpose
        $id = preg_replace("![\\[\\]]{1,2}!", "-", $name);
        if ($id[strlen($id) - 1] == "-") {
            $id = substr($id, 0, -1);
        }
        // wrap to container
        $html = "<div id='{$id}'>{$html}</div>";
        // javascript here
        $html .= <<<HTML
        <script type='text/javascript'>
        \$(function() {
            'use strict';
            var name = '{$name}[region]';
            var url  = '{$url}';
            var container = \$('#{$id}');

            var target  = container.find("div.region");
            var loader  = container.find(".loading");
            var old_val = target.find("select, input").val();

            container.find('select[name\$="[country]"]').change(function() {
                loader.show();
                \$.post(url, {
                    country: this.value }, function(r) {
                        if (r.data && r.data.options
                                && r.data.oOrder && r.data.oOrder.length)
                        {
                            var select = \$(
                                    "<select name='" + name + "'>" +
                                    "<option value=''></option>" +
                                    "</select>"
                            );
                            var o, selected = false;
                            for (var i = 0; i < r.data.oOrder.length; i++) {
                                o = \$("<option></option>").attr(
                                        "value", r.data.oOrder[i]
                                ).text(
                                        r.data.options[r.data.oOrder[i]]
                                ).attr(
                                        "disabled", r.data.oOrder[i] === ""
                                );
                                if (!selected && old_val === r.data.oOrder[i]) {
                                    o.attr("selected", true);
                                    selected = true;
                                }
                                select.append(o);
                            }
                            target.find(".not-empty select").replaceWith(select);
                            target.find(".not-empty").show();

                            target.find(".empty input").attr("disabled", true);
                            target.find(".empty").hide();

                        } else {
                            target.find(".empty input").attr("disabled", false);
                            target.find(".empty").show();

                            target.find(".not-empty select").attr("disabled", true);
                            target.find(".not-empty").hide();

                        }
                        loader.hide();
                    }, "json");
            });

            container.on("change", 'select[name="' + name + '"]', function() {
                old_val = this.value;
            });

        });
        </script>
HTML;
        return $html;
    }
 /**
  * Make sure given array of options is valid for $field.
  * Return list($local_opts, $sys_opts) to save for this $field.
  * Local options are saved to shop app config. System options to contacts app config.
  * If any of option sets returned is null, this field is skipped altogether.
  */
 protected static function tidyOpts($field, $fld_id, $opts)
 {
     if ($fld_id == '%FID%' || !is_array($opts) || !empty($opts['_deleted']) || empty($opts['localized_names'])) {
         return array(null, null);
     }
     if (!empty($opts['_disabled'])) {
         if (!empty($opts['_default_value_enabled']) && isset($opts['_default_value']) && strlen($opts['_default_value'])) {
             // A hack for region field: when user specifies region name, replace it with region code.
             // In case there's a region with code equal to another region's name, prefer the former.
             if ($field instanceof waContactRegionField) {
                 $rm = new waRegionModel();
                 $regions = $rm->select('code, code AS a')->where('code = s:0 OR name = s:0', $opts['_default_value'])->query()->fetchAll('code', true);
                 if ($regions && empty($regions[$opts['_default_value']])) {
                     $opts['_default_value'] = reset($regions);
                 }
             }
             return array(array('hidden' => true, 'value' => $opts['_default_value']), array());
         } else {
             return array(null, null);
         }
     }
     unset($opts['_disabled'], $opts['_type'], $opts['_deleted'], $opts['_default_value'], $opts['_default_value_enabled']);
     $sys_opts = array();
     if (in_array(get_class($field), array('waContactSelectField', 'waContactRadioSelectField', 'waContactChecklistField', 'waContactBranchField'))) {
         if (!empty($opts['options']) && is_array($opts['options'])) {
             if ($field instanceof waContactBranchField) {
                 if (empty($opts['hide']) || !is_array($opts['hide'])) {
                     $opts['hide'] = array();
                 }
             }
             // get rid of empty last element
             if ($el = trim(array_pop($opts['options']))) {
                 $opts['options'][] = $el;
             }
             $branch_hide = array();
             $select_options = array();
             foreach ($opts['options'] as $i => $v) {
                 $v = trim($v);
                 $select_options[$v] = $v;
                 if ($field instanceof waContactBranchField && !empty($opts['hide'][$i])) {
                     $branch_hide[$v] = explode(',', (string) $opts['hide'][$i]);
                 }
             }
             if (!$select_options) {
                 return array(null, null);
             }
             $sys_opts['options'] = $select_options;
             if ($field instanceof waContactBranchField) {
                 $sys_opts['hide'] = $branch_hide;
             }
         } else {
             if (!$field->getParameter('options')) {
                 // Never allow select-based field with no options to select from
                 return array(null, null);
             }
         }
         unset($opts['options']);
     } else {
         if ($field instanceof waContactCompositeField) {
             if (empty($opts['fields']) || !is_array($opts['fields'])) {
                 return array(null, null);
             }
             $subfields = array();
             $subfields_sys = array();
             $existing_subfields = $field->getFields();
             foreach ($opts['fields'] as $sf_id => $o) {
                 if ($sf_id == '%FID%' || !empty($o['_deleted'])) {
                     continue;
                 }
                 if (empty($existing_subfields[$sf_id])) {
                     $sf = self::createFromOpts($o, $opts['fields'] + $existing_subfields);
                     if (!$sf) {
                         continue;
                     }
                     // For conditional fields, update ID in database: replace temporary id with new one
                     if ($sf instanceof waContactConditionalField) {
                         $cfvm = new waContactFieldValuesModel();
                         $cfvm->changeField($sf_id, $sf->getId());
                     }
                     $sf_id = $sf->getId();
                 } else {
                     $sf = $existing_subfields[$sf_id];
                     $subfields_sys[$sf_id] = $sf;
                     // make sure it is saved to system config
                 }
                 list($o, $sys_o) = self::tidyOpts($sf, $sf_id, $o);
                 if ($o === null || $sys_o === null) {
                     continue;
                 }
                 if ($sf instanceof waContactConditionalField) {
                     $sys_o['parent_id'] = $fld_id;
                 }
                 $sf->setParameters($sys_o);
                 $subfields_sys[$sf_id] = $sf;
                 $subfields[$sf_id] = $o;
             }
             if (!$subfields) {
                 return array(null, null);
             }
             $opts['fields'] = $subfields;
             $sys_opts['fields'] = $subfields_sys;
         }
     }
     if ($field->getParameter('app_id') == 'shop') {
         $sys_opts += $opts;
         $opts = array();
         foreach (waContactFields::$customParameters as $k => $v) {
             if (isset($sys_opts[$k])) {
                 $opts[$k] = $sys_opts[$k];
             }
         }
     }
     if (empty($opts) && $opts !== null) {
         $opts = array('__dummy__' => 1);
     }
     return array($opts, $sys_opts);
 }
Example #8
0
 /**
  * Returns customer's shipping address written in one string.
  *
  * @param array $order_params 'params' element of order data array returned by getOrder() method of shopOrderModel class
  * @param bool $for_map Whether full or brief address information must be returned; defaults to true
  * @return string
  */
 public static function getShippingAddressText($order_params, $for_map = true)
 {
     $address = array();
     foreach (waContactFields::get('address')->getFields() as $k => $v) {
         $address[$k] = ifset($order_params['shipping_address.' . $k]);
     }
     if ($for_map) {
         $address_f = array();
         foreach (array('country', 'region', 'zip', 'city', 'street') as $k) {
             if (!isset($address[$k])) {
                 continue;
             } elseif ($k == 'country') {
                 $address_f[$k] = waCountryModel::getInstance()->name(ifempty($address['country']));
             } elseif ($k == 'region') {
                 $address_f['region'] = '';
                 if (!empty($address['country']) && !empty($address['region'])) {
                     $model = new waRegionModel();
                     if ($region = $model->get($address['country'], $address['region'])) {
                         $address_f['region'] = $region['name'];
                     }
                 }
             } else {
                 $address_f[$k] = $address[$k];
             }
         }
         return implode(', ', $address_f);
     }
     return implode(', ', $address);
 }
 protected function getTaxCountries($tax, $countries)
 {
     $tax_countries = array();
     // Collect data for all countries that have tax rates set
     foreach ($this->trm->getByTax($tax['id']) as $r) {
         // Init country
         if (!isset($tax_countries[$r['country_iso3']])) {
             switch ($r['country_iso3']) {
                 case '%AL':
                     $c = array('name' => _w('All countries'));
                     break;
                 case '%EU':
                     $c = array('name' => _w('All European countries'));
                     break;
                 case '%RW':
                     $c = array('name' => _w('Rest of world'));
                     break;
                 default:
                     $c = ifset($countries[$r['country_iso3']], array('name' => 'Unknown country: ' . $r['country_iso3']));
                     break;
             }
             $tax_countries[$r['country_iso3']] = array('css_class' => null, 'iso3' => $r['country_iso3'], 'name' => $c['name'], 'regions_data' => array(), 'global_rate' => null, 'regions' => array());
         }
         // Remember regions data to process later
         if ($r['region_code'] === null) {
             $tax_countries[$r['country_iso3']]['global_rate'] = (double) str_replace(',', '.', $r['tax_value']);
         } else {
             $tax_countries[$r['country_iso3']]['regions_data'][$r['region_code']] = $r;
         }
     }
     // Init regions
     $rm = new waRegionModel();
     foreach ($rm->getByCountry(array_keys($tax_countries)) as $r) {
         $c =& $tax_countries[$r['country_iso3']];
         if (!$c['regions_data']) {
             $r['css_class'] = 'hidden';
         } else {
             if ($c['global_rate'] === null) {
                 $r['css_class'] = 'regions_simple';
             } else {
                 $r['css_class'] = 'regions_advanced';
             }
         }
         if (empty($c['regions_data'][$r['code']])) {
             $r['tax_name'] = '';
             $r['tax_value'] = '';
             $r['params'] = array('tax_value_modifier' => '+');
         } else {
             $r = $c['regions_data'][$r['code']] + $r;
             $r['params'] = $r['params'] ? unserialize($r['params']) : array('tax_value_modifier' => '');
             $r['tax_value'] = (double) str_replace(',', '.', $r['tax_value']);
         }
         $c['regions'][] = $r;
     }
     unset($c);
     // Cleanup
     foreach ($tax_countries as &$c) {
         if (!$c['regions_data']) {
             $c['css_class'] = 'one_rate';
         } else {
             if ($c['global_rate'] === null) {
                 $c['css_class'] = 'regions_simple';
             } else {
                 $c['css_class'] = 'regions_advanced';
             }
         }
         unset($c['regions_data']);
     }
     unset($c);
     // Sort countries by name
     uasort($tax_countries, array($this, 'sortHelper'));
     return $tax_countries;
 }
    public function getHtmlOne($params = array(), $attrs = '')
    {
        $value = isset($params['value']) ? $params['value'] : '';
        $ext = null;
        $multi_suffix = '';
        if (is_array($value)) {
            $ext = $value['ext'];
            $value = $value['value'];
        }
        $name_input = $name = $this->getHTMLName($params);
        if ($this->isMulti()) {
            $name_input .= '[value]';
        }
        $country = ifset($params['composite_value']['country']);
        $region_countries = array_fill_keys($this->getRegionCountries(), 1);
        if (!$region_countries || empty($country) && empty($params['parent'])) {
            // The simplest case: just show <input> with no logic at all.
            return '<input type="text" name="' . htmlspecialchars($name_input) . '" value="' . htmlspecialchars($value) . '" ' . $attrs . '>';
        }
        //
        // So, we're a part of a composite field with a Country subfield.
        // Need to show <select> with regions, if selected country has them,
        // or <input> when no country selected or has no regions.
        // In case user changes the country, we should load new regions via XHR.
        // And on top of that, field should behave reasonably when JS is off!
        //
        // When country is selected and has regions, build a <select> with appropriate options.
        $region_select = null;
        if ($country) {
            // List of regions for this country
            $rm = new waRegionModel();
            $options = array('<option value="">' . htmlspecialchars('<' . _ws('select region') . '>') . '</option>');
            $selected = false;
            foreach ($rm->getByCountryWithFav($country) as $row) {
                if (strlen($row['name']) <= 0) {
                    $options[] = '<option disabled>&nbsp;</option>';
                } else {
                    if (!$selected && ($value == $row['code'] || $value == $row['name'])) {
                        $at = ' selected';
                        $selected = true;
                    } else {
                        $at = '';
                    }
                    $options[] = '<option value="' . htmlspecialchars($row['code']) . '"' . $at . '>' . htmlspecialchars($row['name']) . '</option>';
                }
            }
            if (count($options) > 1) {
                // Selected country has regions. Show as <select>.
                $region_select = '<select name="' . htmlspecialchars($name_input) . '" ' . $attrs . ">\n\t" . implode("\n\t", $options) . "\n</select>";
            }
        }
        $html = '';
        if ($region_select) {
            // Selected country has regions. Select field with regions is visible.
            // There's a hidden <input> to switch to when user changes country.
            $html .= $region_select;
            $html .= '<input type="text" ' . $attrs . ' style="display:none;">';
        } else {
            // No country selected or country has no regions.
            // <input> is visible and <select> is hidden.
            $html .= '<select ' . $attrs . ' style="display:none;"></select>';
            $html .= '<input type="text" name="' . htmlspecialchars($name_input) . '" value="' . htmlspecialchars($value) . '" ' . $attrs . '>';
        }
        // JS to load regions when user changes country.
        $p = $params;
        $p['id'] = 'country';
        $name_country = $this->getHTMLName($p);
        if (wa()->getEnv() == 'backend') {
            $xhr_url = ifset($params['xhr_url'], wa()->getAppUrl('webasyst') . '?module=backend&action=regions');
        } else {
            $xhr_url = ifset($params['xhr_url'], wa()->getRouteUrl('/frontend/regions'));
        }
        $region_countries = json_encode($region_countries);
        $empty_option = '<' . _ws('select region') . '>';
        $js = <<<EOJS
<script>if(\$){ \$(function() {
    var region_countries = {$region_countries};
    var input_name = "{$name_input}";
    var country_select = \$('[name="{$name_country}"]');
    var xhr_url = "{$xhr_url}";
    if (country_select.length <= 0) {
        return;
    }

    var select;
    var input = \$('[name="'+input_name+'"]');
    if (input.length <= 0) {
        return;
    }
    if (input.is('input')) {
        select = input.prev();
    } else {
        select = input;
        input = select.next();
    }

    var showInput = function() {
        if (!input[0].hasAttribute('name')) {
            input.attr('name', select.attr('name'))
            select[0].removeAttribute('name');
        }
        input.show().val('');
        select.hide();
    };

    var getVal = function() {
        if (input.is(':visible')) {
            return input.val();
        } else {
            return select.val();
        }
    };

    var change_handler;
    country_select.change(change_handler = function() {
        var old_val = getVal();
        var country = country_select.val();
        input.prev('.loading').remove();
        if (region_countries && region_countries[country]) {
            showInput();
            input.before('<i class="icon16 loading"></i>');
            \$.post(xhr_url, { country: country }, function(r) {
                input.prev('.loading').remove();
                if (r.data && r.data.options && r.data.oOrder) {
                    input.hide();
                    select.show().children().remove();
                    select.append(\$('<option value=""></option>').text("{$empty_option}"));
                    var o, selected = false;
                    for (i = 0; i < r.data.oOrder.length; i++) {
                        o = \$('<option></option>').attr('value', r.data.oOrder[i]).text(r.data.options[r.data.oOrder[i]]).attr('disabled', r.data.oOrder[i] === '');
                        if (!selected && old_val === r.data.oOrder[i]) {
                            o.attr('selected', true);
                            selected = true;
                        }
                        select.append(o);
                    }
                    if (input[0].hasAttribute('name')) {
                        select.attr('name', input.attr('name'));
                        input[0].removeAttribute('name');
                    }
                } else {
                    showInput();
                    input.val(old_val);
                }
            }, 'json');
        } else {
            if (!input.is(':visible')) {
                showInput();
                input.val(old_val);
            }
        }
    });
    change_handler.call(country_select);
});};</script>
EOJS;
        return $html . $js;
    }
Example #11
0
 private function init_address(&$address)
 {
     static $model;
     if (empty($address['country_name'])) {
         $address['country_name'] = waCountryModel::getInstance()->name(ifempty($address['country']));
     }
     if (empty($address['region_name'])) {
         $address['region_name'] = '';
         if (!empty($address['country']) && !empty($address['region'])) {
             if (!$model) {
                 $model = new waRegionModel();
             }
             if ($region = $model->get($address['country'], $address['region'])) {
                 $address['region_name'] = $region['name'];
             }
         }
     }
     if (empty($address['address'])) {
         $fields = array('street', 'city', 'region_name', 'zip', 'country_name');
         $address['address'] = '';
         $chunks = array();
         foreach ($fields as $field) {
             if (!empty($address[$field])) {
                 $chunks[] = $address[$field];
             }
         }
         $address['address'] = implode(', ', $chunks);
         if (preg_match('/^(.{1,119}),\\s+(.*)$/', $address['address'], $matches)) {
             $address['address_1'] = $matches[1];
             $address['address_2'] = $matches[2];
         } else {
             $address['address_1'] = $address['address'];
             $address['address_2'] = '';
         }
         $address['name'] = '';
         $fields = array('firstname', 'lasname', 'middlename');
         foreach ($fields as $field) {
             if (!empty($address[$field])) {
                 $address['name'] .= ' ' . $address[$field];
             }
         }
         $address['name'] = trim($address['name']);
     }
 }
 public function execute()
 {
     $category_id = waRequest::request('category', 0, 'int');
     $search = waRequest::request('search');
     $start = waRequest::request('start', 0, 'int');
     $limit = 50;
     $order = waRequest::request('order', '!last_order');
     $config = $this->getConfig();
     $use_gravatar = $config->getGeneralSettings('use_gravatar');
     $gravatar_default = $config->getGeneralSettings('gravatar_default');
     // Get customers
     $scm = new shopCustomerModel();
     list($customers, $total) = $scm->getList($category_id, $search, $start, $limit, $order);
     $has_more = $start + count($customers) < $total;
     $countries = array();
     foreach ($customers as &$c) {
         $c['affiliate_bonus'] = (double) $c['affiliate_bonus'];
         if (!$c['photo'] && $use_gravatar) {
             $c['photo'] = shopHelper::getGravatar(!empty($c['email']) ? $c['email'] : '', 50, $gravatar_default);
         } else {
             $c['photo'] = waContact::getPhotoUrl($c['id'], $c['photo'], 50, 50);
         }
         $c['categories'] = array();
         if (!empty($c['address']['region']) && !empty($c['address']['country'])) {
             $countries[$c['address']['country']] = array();
         }
     }
     unset($c);
     // Add region names to addresses
     if ($countries) {
         $rm = new waRegionModel();
         foreach ($rm->where('country_iso3 IN (?)', array_keys($countries))->query() as $row) {
             $countries[$row['country_iso3']][$row['code']] = $row['name'];
         }
         foreach ($customers as &$c) {
             if (!empty($c['address']['region']) && !empty($c['address']['country'])) {
                 $country = $c['address']['country'];
                 $region = $c['address']['region'];
                 if (!empty($countries[$country]) && !empty($countries[$country][$region])) {
                     $c['address']['region_formatted'] = $countries[$country][$region];
                 }
             }
         }
         unset($c);
     }
     // Contact categories
     $ccm = new waContactCategoryModel();
     $categories = $ccm->getAll('id');
     if ($customers) {
         $ccsm = new waContactCategoriesModel();
         foreach ($ccsm->getContactsCategories(array_keys($customers)) as $c_id => $list) {
             foreach ($list as $cat_id) {
                 if (!empty($categories[$cat_id])) {
                     $customers[$c_id]['categories'][$cat_id] = $categories[$cat_id];
                 }
             }
         }
     }
     // Set up lazy loading
     if (!$has_more) {
         // Do not trigger lazy loading, show total count at end of list
         $total_customers_number = $start + count($customers);
     } else {
         $total_customers_number = null;
         // trigger lazy loading
     }
     // List title and other params depending on list type
     if ($search) {
         $title = _w('Search results');
         $hash_start = '#/search/0/' . urlencode($search) . '/';
         $discount = null;
     } else {
         if ($category_id) {
             if (!empty($categories[$category_id])) {
                 $title = $categories[$category_id]['name'];
             } else {
                 $title = _w('Unknown category') . ' ' . $category_id;
             }
             $hash_start = '#/category/' . $category_id . '/';
             if (wa()->getSetting('discount_category')) {
                 $ccdm = new shopContactCategoryDiscountModel();
                 $discount = sprintf_wp('%s%% discount', $ccdm->getDiscount($category_id));
             } else {
                 $discount = null;
             }
         } else {
             $title = _w('All customers');
             $hash_start = '#/all/0/';
             $discount = null;
         }
     }
     $lazy_loading_params = array('limit=' . $limit, 'start=' . ($start + $limit), 'order=' . $order);
     if ($search) {
         $lazy_loading_params[] = 'search=' . $search;
     } else {
         if ($category_id) {
             $lazy_loading_params[] = 'category=' . $category_id;
         }
     }
     $lazy_loading_params = implode('&', $lazy_loading_params);
     $this->view->assign('cols', self::getCols());
     $this->view->assign('title', $title);
     $this->view->assign('order', $order);
     $this->view->assign('total', $total);
     $this->view->assign('discount', $discount);
     $this->view->assign('customers', $customers);
     $this->view->assign('hash_start', $hash_start);
     $this->view->assign('category_id', $category_id);
     $this->view->assign('lazy_loading_params', $lazy_loading_params);
     $this->view->assign('total_customers_number', $total_customers_number);
 }
 public function allowedAddress()
 {
     $cache = new waSerializeCache(__CLASS__ . __FUNCTION__, 86400, 'webasyst');
     if (!($addresses = $cache->get())) {
         $addresses = array();
         /* countries */
         $countries = $this->request('ems.get.locations', array('type' => 'countries'));
         $country_model = new waCountryModel();
         $map = $country_model->getAll('iso2letter');
         $address = array('country' => array());
         foreach ($countries['locations'] as $country) {
             if (ifset($country['type']) == 'countries' && ($value = strtolower(ifset($country['value']))) && isset($map[$value])) {
                 $address['country'][] = $map[$value]['iso3letter'];
             }
         }
         $addresses[] = $address;
         /* regions */
         $region_model = new waRegionModel();
         $address = array('country' => 'rus', 'region' => array());
         $map = $region_model->getByCountry('rus');
         foreach ($map as $region) {
             if ($this->findTo(array('country' => 'rus', 'region_name' => $region['name']))) {
                 $address['region'][] = $region['code'];
             }
         }
         $addresses[] = $address;
         $cache->set($addresses);
     }
     return $addresses;
 }
    public function getHtmlOne($params = array(), $attrs = '')
    {
        $value = isset($params['value']) ? $params['value'] : '';
        $ext = null;
        $multi_suffix = '';
        if (is_array($value)) {
            $ext = $value['ext'];
            $value = $value['value'];
        }
        if (preg_match('~(?:\\s|")id="([^"]+)"~', ' ' . $attrs, $matches)) {
            $select_id = $matches[1];
            $attrs = trim(preg_replace('~(\\s|")id="([^"]+)"~', '$1 ', ' ' . $attrs));
        } else {
            $select_id = uniqid('s');
        }
        $input_id = $select_id . '-input';
        $name_input = $name = $this->getHTMLName($params);
        if ($this->isMulti()) {
            $name_input .= '[value]';
        }
        $country = ifset($params['composite_value']['country']);
        $region_countries = array_fill_keys($this->getRegionCountries(), 1);
        if (!$region_countries || empty($country) && empty($params['parent'])) {
            // The simplest case: just show <input> with no logic at all.
            return '<input type="text" name="' . htmlspecialchars($name_input) . '" value="' . htmlspecialchars($value) . '" ' . $attrs . '>';
        }
        //
        // So, we're a part of a composite field with a Country subfield.
        // Need to show <select> with regions, if selected country has them,
        // or <input> when no country selected or has no regions.
        // In case user changes the country, we should load new regions via XHR.
        // And on top of that, field should behave reasonably when JS is off!
        //
        // When country is selected and has regions, build a <select> with appropriate options.
        $region_select = null;
        if ($country && !is_array($country)) {
            // List of regions for this country
            $rm = new waRegionModel();
            $options = array('<option value="">' . htmlspecialchars('<' . _ws('select region') . '>') . '</option>');
            $selected = false;
            foreach ($rm->getByCountryWithFav($country) as $row) {
                if (strlen($row['name']) <= 0) {
                    $options[] = '<option disabled>&nbsp;</option>';
                } else {
                    if (!$selected && ($value == $row['code'] || $value == $row['name'])) {
                        $at = ' selected';
                        $selected = true;
                    } else {
                        $at = '';
                    }
                    $options[] = '<option value="' . htmlspecialchars($row['code']) . '"' . $at . '>' . htmlspecialchars($row['name']) . '</option>';
                }
            }
            if (count($options) > 1) {
                // Selected country has regions. Show as <select>.
                $region_select = '<select name="' . htmlspecialchars($name_input) . '" data-country="' . htmlspecialchars($country) . '" id="' . $select_id . '" ' . $attrs . ">\n\t" . implode("\n\t", $options) . "\n</select>";
            }
        }
        $html = '';
        if ($region_select) {
            // Selected country has regions. Select field with regions is visible.
            // There's a hidden <input> to switch to when user changes country.
            $html .= $region_select;
            $html .= '<input type="text" id="' . $input_id . '" ' . $attrs . ' style="display:none;">';
        } else {
            // No country selected or country has no regions.
            // <input> is visible and <select> is hidden.
            $html .= '<select id="' . $select_id . '" ' . $attrs . ' style="display:none;"></select>';
            $html .= '<input type="text" id="' . $input_id . '" name="' . htmlspecialchars($name_input) . '" value="' . htmlspecialchars($value) . '" ' . $attrs . '>';
        }
        // JS to load regions when user changes country.
        $p = $params;
        $p['id'] = 'country';
        $name_country = $this->getHTMLName($p);
        if (wa()->getEnv() == 'backend') {
            $xhr_url = ifset($params['xhr_url'], wa()->getAppUrl('webasyst') . '?module=backend&action=regions');
        } else {
            $xhr_url = ifset($params['xhr_url'], wa()->getRouteUrl('/frontend/regions'));
        }
        $crossDomain = ifset($params['xhr_cross_domain'], 0);
        $dataType = isset($params['xhr_cross_domain']) ? 'jsonp' : 'json';
        $region_countries = str_replace("{", "{ ", str_replace("}", " }", json_encode($region_countries)));
        $empty_option = '<' . _ws('select region') . '>';
        $js = <<<EOJS
<script>if(\$){ \$(function() {
    // List of countries we have regions for
    var region_countries = {$region_countries};

    // Country selector regions depend on
    var country_select = \$('[name="{$name_country}"]');
    if (country_select.length <= 0) {
        return;
    }

    // <select> and <input> fields that are parts of this region controller
    var select = \$('#{$select_id}');
    var input = \$('#{$input_id}');
    if (input.length <= 0 || select.length <= 0) {
        return;
    }

    // URL to fetch list of regions from
    var xhr_url = "{$xhr_url}";

    // Helper to hide <select> and show <input>
    var showInput = function(val) {
        if (!input[0].hasAttribute('name')) {
            input.attr('name', select.attr('name'))
            select[0].removeAttribute('name');
        }
        input.show().val(val || '');
        select.hide();
    };

    // Helper to hide <input> and show <select>
    var showSelect = function() {
        if (input[0].hasAttribute('name')) {
            select.attr('name', input.attr('name'));
            input[0].removeAttribute('name');
        }
        select.show();
        input.hide();
    };

    // Returns currently selected value of <select> or value of <input>
    var getVal = function() {
        if (input.is(':visible')) {
            return input.val();
        } else {
            return select.val();
        }
    };

    // When user changes country, update region selector.
    var change_handler;
    country_select.change(change_handler = function() {
        var old_val = getVal(); // previous user-selected option in <select> or value of <input>
        var country = country_select.val();
        input.prev('.loading').remove();

        // When <select> already has regions for this country loaded, just show it without XHR.
        var previously_selected = select.data('country');
        if (previously_selected && country == previously_selected) {
            showSelect();
            return;
        }

        if (region_countries && region_countries[country]) {
            // Selected country has regions. Load them into <select> via XHR.
            showInput('');
            input.before('<i class="icon16 loading"></i>');
            \$.ajax(xhr_url, {
                type: 'post',
                crossDomain: {$crossDomain},
                data: { country: country },
                dataType: '{$dataType}',
                success: function(r) {
                    input.prev('.loading').remove();
                    if (r.data && r.data.options && r.data.oOrder) {
                        select.children().remove();
                        select.append(\$('<option value=""></option>').text("{$empty_option}"));
                        var o, selected = false;
                        for (i = 0; i < r.data.oOrder.length; i++) {
                            o = \$('<option></option>').attr('value', r.data.oOrder[i]).text(r.data.options[r.data.oOrder[i]]).attr('disabled', r.data.oOrder[i] === '');
                            if (!selected && old_val === r.data.oOrder[i]) {
                                o.attr('selected', true);
                                selected = true;
                            }
                            select.append(o);
                        }
                        select.data('country', country);
                        showSelect();
                    } else {
                        showInput('');
                    }
                }
            });
        } else {
            // Selected country has no regions. Show <input>.
            if (!input.is(':visible')) {
                showInput('');
            }
        }
    });
    change_handler.call(country_select[0]);
});};</script>
EOJS;
        return $html . $js;
    }