mPrice = $price; $this->mOptions = $options; $this->mStartTm = $start; $this->mEndTm = $end; $this->mRepeat = $repeat; $this->mSpecialID = $special_id; $this->mGoods = []; } public function match($goods_nums) { if($this->acting() == false) return false; $gids = array_keys($goods_nums); sort($gids); $match_gids = algorithm::set_intersection($this->mGoods,$gids); $matched = false; if($this->mRepeat == false) { if(count($match_gids) >= $this->mOptions) { $matched = true; } } else { $goods_num = $this->goods_num($match_gids, $goods_nums); if ($goods_num >= $this->mOptions) { $matched = true; } } if($matched) { $matched_goods = []; foreach ($match_gids as $gid) { $matched_goods[$gid] = $goods_nums[$gid]; } return ['goods_nums' => $matched_goods,'price' => $this->mPrice,'options' => $this->mOptions,'repeat' => $this->mRepeat]; } else { return false; } } public function info($gid) { if($this->acting() == false) return false; if(algorithm::binary_search($this->mGoods,$gid)) { $result['special_id'] = $this->mSpecialID; $price = $this->mPrice / 100; $result['desc'] = "{$price}元任选{$this->mOptions}件"; $result['short_desc'] = "{$price}选{$this->mOptions}"; return $result; } else { return false; } } private function goods_num($gids,$gid_nums) { $num = 0; foreach ($gids as $gid) { $num += $gid_nums[$gid]; } return $num; } public function add_goods($gid) { $gid = intval($gid); if($gid <= 0) return false; if(algorithm::binary_search($this->mGoods,$gid)) { return false; } else { $pos = algorithm::lower_bonud($this->mGoods,$gid); algorithm::array_insert($this->mGoods,$pos,$gid); return true; } } public function acting() { $cur_tm = time(); return ($cur_tm >= $this->mStartTm && $cur_tm < $this->mEndTm); } public function equal($price,$options) { return ($this->mPrice == $price && $this->mOptions == $options); } } class optional_goods { private $mAllGoods; private $mOpgroups; private $mSpecials; private $mErrGoods; static private $stInstance = null; private function __construct() { $this->mOpgroups = []; $this->mAllGoods = []; $this->mSpecials = []; $this->mErrGoods = []; } static public function instance() { if (self::$stInstance == null) { self::$stInstance = new optional_goods(); } if (StatesHelper::fetch_state('optional_goods')) { Log::record("optional_goods reinit data.", Log::DEBUG); self::$stInstance->init(); } return self::$stInstance; } public function layout_error() { if (empty($this->mErrGoods)) { return false; } else { return $this->mErrGoods; } } public function all_goods() { return $this->mAllGoods; } public function exist_goods($gid) { $gid = intval($gid); if ($gid <= 0) return false; if (algorithm::binary_search($this->mAllGoods, $gid)) { return true; } else { return false; } } public function info($goods_id) { $gid = intval($goods_id); if ($gid <= 0) return false; if (algorithm::binary_search($this->mAllGoods, $gid)) { foreach ($this->mOpgroups as $group) { $info = $group->info($gid); if($info == false) continue; if($group->acting() == false) { return false; } else { return $info; } } return false; } else { return false; } } public function match($gidnums) { $input_goods = $this->input_goods($gidnums); $match_goods = algorithm::set_intersection($this->mAllGoods, $input_goods); if (empty($match_goods)) return false; $match_goods = $this->sel_goods($match_goods, $gidnums); $result = []; foreach ($this->mOpgroups as $opgroup) { if (empty($match_goods)) break; $part = $opgroup->match($match_goods); if ($part != false) { $result[] = $part; $goods_nums = $part['goods_nums']; foreach ($goods_nums as $gid => $num) { unset($match_goods[$gid]); } } } return $result; } private function sel_goods($gids, $gidnums) { $result = []; foreach ($gids as $gid) { $result[$gid] = $gidnums[$gid]; } return $result; } private function input_goods($gidnums) { $result = []; foreach ($gidnums as $gid => $num) { if ($num > 0) { $result[] = $gid; } } sort($result); return $result; } private function init() { global $config; $opids = $config['optional_goods']; if (empty($opids)) return true; $this->mOpgroups = []; $this->mAllGoods = []; $this->mSpecials = []; $this->mErrGoods = []; $this->mSpecials = array_unique($opids); foreach ($this->mSpecials as $special_id) { $this->add_special($special_id); } sort($this->mErrGoods); } private function add_special($special_id) { $mod_special = Model('mb_special'); $ret = $mod_special->getMbSpecialItemUsableListByID($special_id); $blocks = $ret['blocks']; $cur_group = null; foreach ($blocks as $block) { $type = $block['item_type']; if ($type == 'home1') { $tmp_group = $this->add_group($block, $special_id); if ($tmp_group != null) { $cur_group = $tmp_group; $this->mOpgroups[] = $cur_group; } } else { $this->add_goods($cur_group, $block); } } } private function add_goods($group, $block) { $items = $block['items']; if (empty($items)) return; foreach ($items as $item) { if (array_key_exists('type', $item) && $item['type'] == 'goods') { $goods_id = intval($item['data']); $spugids = $this->spu_goods($goods_id); if($spugids == false) continue; foreach ($spugids as $goods_id) { if ($group != null && $goods_id > 0 && $this->exist_goods($goods_id) == false) { if ($group->add_goods($goods_id)) { $this->addgoods($goods_id); } } else { $this->mErrGoods[] = $goods_id; } } } } } private function spu_goods($gid) { $cid = commonid_helper::instance()->common_id($gid); if($cid != false) { $gids = commonid_helper::instance()->goods_ids($cid); if($gids == false) return false; if(count($gids) == 1) { return $gids; } else { $goods_map = []; $mod_goods = Model('goods'); $goodses = $mod_goods->getGoodsOnlineList(array('goods_id' => array('in', $gids))); foreach ($goodses as $goods) { $gid = intval($goods['goods_id']); $goods_map[$gid] = $goods['goods_price']; } $goods_price = $goods_map[$gid]; $result = []; foreach ($goods_map as $goods_id => $price) { if($price == $goods_price) { $result[] = $goods_id; } } return empty($result) ? false : $result; } } else { return false; } } private function add_group($block,$special_id) { $items = $block['items']; if(empty($items)) return null; $reserved = $items['reserved']; $params = preg_split("/#/",$reserved); if(count($params) == 5) { $price = intval($params[0] * 100 + 0.5); $options = intval($params[1]); $repeat = intval($params[2]) == 1 ? true : false; $startm = strtotime($params[3]); $hours = intval($params[4]); if($price > 0 && $options > 1) { $group = $this->find($price,$options); if($group == null) { if($startm > 0 && $hours > 0 && $startm + 3600 * $hours > time()) { $group = new opgroup($price,$options,$startm,$startm + 3600 * $hours,$repeat,$special_id); } } return $group; } else { return null; } } } private function find($price,$options) { foreach ($this->mOpgroups as $item) { if($item->equal($price,$options)) { return $item; } } return null; } private function addgoods($gid) { $gid = intval($gid); if($gid <= 0) return false; if(algorithm::binary_search($this->mAllGoods,$gid)) { return false; } else { $pos = algorithm::lower_bonud($this->mAllGoods,$gid); algorithm::array_insert($this->mAllGoods,$pos,$gid); return true; } } }