/**
  * Public function that creates a single instance
  */
 public static function getInstance()
 {
     if (!isset(self::$_instance)) {
         self::$_instance = new self();
     }
     return self::$_instance;
 }
 /**
  * Handle drawing list of delivery methods
  * @param array $tag_params
  * @param array $children
  */
 public function tag_DeliveryMethodsList($tag_params, $children)
 {
     $manager = ShopDeliveryMethodsManager::getInstance();
     $conditions = array();
     $item_id = -1;
     $selected = -1;
     if (isset($tag_params['item'])) {
         $item_id = fix_id($tag_params['item']);
     }
     if (isset($tag_params['selected'])) {
         $selected = fix_id($tag_params['selected']);
     }
     // delivery method list needs to be filtered by the items in shooping cart
     if (isset($tag_params['shopping_cart']) && $tag_params['shopping_cart'] == 1) {
         $relations_manager = ShopDeliveryItemRelationsManager::getInstance();
         $prices_manager = ShopDeliveryMethodPricesManager::getInstance();
         $items_manager = ShopItemManager::getInstance();
         $cart = isset($_SESSION['shopping_cart']) ? $_SESSION['shopping_cart'] : array();
         $uid_list = array_keys($cart);
         if (count($uid_list) == 0) {
             return;
         }
         // shopping cart contains only UIDs, we need IDs
         $id_list = array();
         $items = $items_manager->getItems(array('id'), array('uid' => $uid_list));
         if (count($items) > 0) {
             foreach ($items as $item) {
                 $id_list[] = $item->id;
             }
         }
         // get item relations to delivery methods
         $relations = $relations_manager->getItems($relations_manager->getFieldNames(), array('item' => $id_list));
         $price_list = array();
         $price_count = array();
         if (count($relations) > 0) {
             foreach ($relations as $relation) {
                 $price_list[] = $relation->price;
                 if (!array_key_exists($relation->price, $price_count)) {
                     $price_count[$relation->price] = 0;
                 }
                 // store number of times price is used
                 $price_count[$relation->price]++;
             }
         }
         $relations = $prices_manager->getItems(array('id', 'method'), array('id' => $price_list));
         $method_count = array();
         if (count($relations) > 0) {
             foreach ($relations as $relation) {
                 $key = $relation->method;
                 if (!array_key_exists($key, $method_count)) {
                     $method_count[$key] = 0;
                 }
                 // increase method usage count with number of price usages
                 $method_count[$key] += $price_count[$relation->id];
             }
         }
         // We compare number of items with method associated with
         // that item. Methods that have number same as number of items
         // are supported and we include them in list.
         $border_count = count($id_list);
         $valid_methods = array();
         if (count($method_count) > 0) {
             foreach ($method_count as $id => $count) {
                 if ($count == $border_count) {
                     $valid_methods[] = $id;
                 }
             }
         }
         if (count($valid_methods) > 0) {
             $conditions['id'] = $valid_methods;
         } else {
             $conditions['id'] = -1;
         }
         // filter by location
         $shop_location = isset($this->_parent->settings['shop_location']) ? $this->_parent->settings['shop_location'] : '';
         if (!empty($shop_location)) {
             $same_country = $shop_location == $_SESSION['buyer']['country'];
             if ($same_country) {
                 $conditions['domestic'] = 1;
             } else {
                 $conditions['international'] = 1;
             }
         }
     }
     // get template
     $template = $this->_parent->loadTemplate($tag_params, 'delivery_methods_list_item.xml');
     $template->registerTagHandler('_price_list', $this, 'tag_DeliveryPricesList');
     // get items from database
     $items = $manager->getItems($manager->getFieldNames(), $conditions);
     if (count($items) > 0) {
         foreach ($items as $item) {
             $params = array('id' => $item->id, 'name' => $item->name, 'international' => $item->international, 'international_char' => $item->international ? CHAR_CHECKED : CHAR_UNCHECKED, 'domestic' => $item->domestic, 'domestic_char' => $item->domestic ? CHAR_CHECKED : CHAR_UNCHECKED, 'item' => $item_id, 'selected' => $selected == $item->id ? 1 : 0, 'item_change' => url_MakeHyperlink($this->_parent->getLanguageConstant('change'), window_Open('shop_delivery_method_change', 370, $this->_parent->getLanguageConstant('title_delivery_method_change'), true, true, url_Make('transfer_control', 'backend_module', array('module', $this->name), array('backend_action', 'delivery_methods'), array('sub_action', 'change'), array('id', $item->id)))), 'item_delete' => url_MakeHyperlink($this->_parent->getLanguageConstant('delete'), window_Open('shop_delivery_method_delete', 400, $this->_parent->getLanguageConstant('title_delivery_method_delete'), false, false, url_Make('transfer_control', 'backend_module', array('module', $this->name), array('backend_action', 'delivery_methods'), array('sub_action', 'delete'), array('id', $item->id)))), 'item_prices' => url_MakeHyperlink($this->_parent->getLanguageConstant('prices'), window_Open('shop_delivery_method_prices', 370, $this->_parent->getLanguageConstant('title_delivery_method_prices'), true, false, url_Make('transfer_control', 'backend_module', array('module', $this->name), array('backend_action', 'delivery_methods'), array('sub_action', 'prices'), array('id', $item->id)))));
             $template->setLocalParams($params);
             $template->restoreXML();
             $template->parse();
         }
     }
 }