public
Created

  • Download Gist
ActionPlan.php
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
<?php defined('SYSPATH') OR die('No direct access allowed.');
 
class Model_ActionPlan extends Mongo_Document
{
/**
* The name of the collection within the database.
*
* @var string
*/
protected $name;
 
/**
* Use the after_load function to check for whether this AP has expired
*/
protected function after_load()
{
// If we don't have info needed to expire this AP, then don't try
if ( ! isset($this->game_id))
return;
if ($this->is_expired())
{
$game = new Model_Game($this->game_id);
$user = Auth::current_user();
$this->close($game, $user, 'failure');
}
}
public function __construct($name = NULL, $id = NULL)
{
if ($name !== NULL)
{
$this->name = 'Stocks.'.$name.'.action_plans';
}
if ($id !== NULL)
{
parent::__construct($id);
}
}
public function is_expired()
{
if (isset($this->expires))
{
$date = self::date_field($this->expires);
if ($date == null)
return false;
return ($date < time());
}
return false;
}
public function close($game, $user, $close_type, $auto_close = false)
{
// First, if this idea has not yet expired, that means it is being closed manually. In that case,
// make sure that this user is a gamemaster. Only gamemasters can close APs.
if ((! $auto_close) AND ($close_type !== 'failure') AND ( ! $this->is_expired()) AND ! $user->is_gamemaster_in_game($game->id))
{
return;
}
 
// Now do the payout
if ($game->config['prediction_market']['ActionPlan'])
{
// For now, you can change a failed AP to success but you cannot change a
// successful one to a fail because it will be hard to remove the awarded points.
if (isset($this->status))
{
$status = $this->status; // This crashes
// $status = parent::__get('status'); // This works
if (($status === "closed") AND ($this->close_type != "failure"))
{
return;
}
}
// Now, get all users who own stock in this AP
$owners = $this->owners;
// Can be 'implemented' or 'failed'
switch ($close_type)
{
case 'successful':
// MAX[10, (c * question_score)]
$c = $game->config['prediction_market']['c'];
$payout_per_share = max(10, $c * $this->score);
foreach ($owners as $owner_id => $quantity)
{
$owner = new Model_User(new MongoId($owner_id));
if ($quantity > 0)
{
$owner->inc('points', $payout_per_share * $quantity);
}
else
{
// If this user short-sold shares (meaning that the quantity
// is negative), the spec says that the buyback price
// is always 10, no matter what the payback other users get is.
$owner->inc('points', 10 * $quantity);
}
$owner->save();
}
break;
case 'failure':
// No payout, but we should keep this here for consistency.
break;
default:
throw new InvalidArgumentException("Invalid parameter to close action plan.");
}
}
$this->status = "closed";
$this->close_type = $close_type;
$this->save();
 
// If this is closed as a success, close it's parent question and all of its
// sibling action plans as failures.
if ($close_type == 'successful')
{
$parent_question = new Model_Question($game->short_name, $this->parent_id);
$parent_question->close($game, $user, 'automatic');
}
}
/**
* Mark an Action Plan as implemented
*/
public function implement($game, $user)
{
// First, stop if this idea has not yet expired or already been implemented.
// Also, only gamemasters can implement APs.
if ($this->is_expired() OR ($this->status == 'implemented') OR (! $user->is_gamemaster_in_game($game->id)))
{
return false;
}
$this->status = "implemented";
$this->save();
return true;
}
private static function date_field($field)
{
if (is_string($field) && strlen($field) > 0)
{
return strtotime($field);
}
elseif ($field instanceof MongoDate)
{
return $field->sec; // we don't care about anything more specific than the seconds.
}
return null;
}
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.