コード例 #1
0
 /**
  * bid on an item
  * only works with those listings that set an opening bid (even if that amount is zero).
  * We use the proxy-bid system here, as used by ebay:
  * @see http://en.wikipedia.org/wiki/Proxy_bid
  * the winning bidder pays the price of the second-highest bid plus the step
  */
 public function bid($id, $bid, array $data = NULL)
 {
     // normalize the data.
     $data = new Store\KVP($data);
     // create an internal transaction if no transaction has been passed in.
     Transaction::start();
     try {
         // we assume the current user is always the bidder
         $bidder = $this->user();
         // if no bidder was passed into the constructor, blow up.
         if (!Souk\Util::validatePositiveInteger($bidder)) {
             throw new Exception('invalid bidder', $bidder);
         }
         // get a row lock on the listing.
         $listing = $this->get($id, TRUE);
         if (!$listing || !$listing->id) {
             throw new Exception('not found', $id);
         }
         // need the current time to do some comparisons.
         $ts = Souk\util::now();
         // don't go anywhere if the bidding is already closed.
         if ($listing->closed) {
             throw new Exception('closed', $listing);
         }
         // can't let the seller bid on the listing.
         if ($listing->seller == $bidder) {
             throw new Exception('invalid bidder', $listing);
         }
         // step is set when it is a biddable item. if it isn't there, don't allow bidding.
         if ($listing->step < 1) {
             throw new Exception('buy only', $listing);
         }
         // has time expired on this listing?
         if ($listing->expires <= $ts) {
             throw new Exception('expired', $listing);
         }
         // make sure we bid enough to challenge the current bid level.
         // if proxy bidding is enabled we still might not win the bid,
         // but at least we pushed it up a bit.
         if ($listing->bid + $listing->step > $bid) {
             throw new Exception('too low', $listing);
         }
         // keep a pristine copy of the listing internally so other wrapper classes can compare
         // afterward and see what changes were made.
         // The Souk\stockpile adapter especially needs this so it can return escrowed bids
         // to the previous bidder.
         $listing->setPriorState($listing);
         // if proxy bidding is enabled, this gets a little more complicated.
         // proxy bidding is where you bid the max you are willing to pay, but only pay
         // one step above the previous bidder's level.
         // This is how ebay runs its auction site.
         // this means when you bid, we track your max amount you are willing to spend, but only
         // bid the minimum. When the next bid comes in, we automatically up your bid for you
         // until you go over your max amount and someone else takes the lead.
         // this approach makes the escrow system more efficient as well since it can excrow your
         // maximum amount all at once, and then refund when you get outbid or refund the difference
         // if you get it for a lower bid.
         if ($data->enable_proxy) {
             // looks like the previous bidder got outbid.
             // track their maximum amount, and set the bid based on one step above the previous bid.
             if ($bid >= $listing->proxybid + $listing->step) {
                 $listing->bid = $listing->proxybid + $listing->step;
                 $listing->proxybid = $bid;
                 $listing->bidder = $bidder;
                 $listing->bidcount = $listing->bidcount + 1;
                 //  the other bidder is still the winner of the bid. our bid didn't go over their
                 // max bid amount. Bump up their bid amount to what we bid, and increment the
                 // bid count by 2, since we bid on it, and they bid back.
             } else {
                 $listing->bid = $bid;
                 $listing->bidcount = $listing->bidcount + 2;
             }
             // in this case, not a proxy bid system, just a straight up english auction.
             // don't worry about previous bidder. we know we bid more than the previous bidder,
             // so pump up the bid to whatever we passed in.
         } else {
             $listing->bid = $bid;
             $listing->bidder = $bidder;
             $listing->bidcount = $listing->bidcount + 1;
         }
         $listing->touch = $ts;
         $this->storage()->bid($listing);
         Transaction::commit();
         // done.
         return $listing;
         // something went wrong ...
     } catch (Exception $e) {
         // revert the transaction ...
         // if it was created internally, remove it.
         Transaction::rollback();
         // toss the exception again.
         throw $e;
     }
 }
コード例 #2
0
 /**
  * what is the item id of the currency, in stockpile?
  */
 protected function currencyId()
 {
     $id = $this->binder->currencyId();
     if (!Util::validatePositiveInteger($id)) {
         throw new Exception('invalid currency id', $id);
     }
     return $id;
 }