Phortune v0
Summary:
Ref T2787. This does very little so far, but makes inroads on accounts and billing. This is mostly just modeled on what Stripe looks like. The objects are:
- **Account**: Has one or more authorized users, who can make manage the account. An example might be "Phacility", and the three of us would be able to manage it. A user may be associated with more than one account (e.g., a corporate account and a personal account) but the UI tries to simplify the common case of a single account.
- **Payment Method**: Something we can get sweet sweet money from; for now, a credit card registered with Stripe. Payment methods are associated with an account.
- **Product**: A good (one time charge) or service (recurring charge). This might be "t-shirt" or "enterprise plan" or "hourly support" or whatever else.
- **Purchase**: Represents a user purchasing a Product for an Account, using a Payment Method. e.g., you bought a shirt, or started a plan, or purchased support.
- **Charge**: Actual charges against payment methods. A Purchase can create more than one charge if it's a plan, or if the first charge fails and we re-bill.
This doesn't fully account for stuff like coupons/discounts yet but they should fit into the model without any issues.
This only implements `Account`, and that only partially.
Test Plan: {F37531}
Reviewers: chad, btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T2787
Differential Revision: https://secure.phabricator.com/D5435
2013-03-28 17:10:34 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
final class PhortuneAccountQuery
|
|
|
|
extends PhabricatorCursorPagedPolicyAwareQuery {
|
|
|
|
|
|
|
|
private $ids;
|
|
|
|
private $phids;
|
|
|
|
private $memberPHIDs;
|
|
|
|
|
|
|
|
public function withIDs(array $ids) {
|
|
|
|
$this->ids = $ids;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function withPHIDs(array $phids) {
|
|
|
|
$this->phids = $phids;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function withMemberPHIDs(array $phids) {
|
|
|
|
$this->memberPHIDs = $phids;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function loadPage() {
|
|
|
|
$table = new PhortuneAccount();
|
|
|
|
$conn = $table->establishConnection('r');
|
|
|
|
|
|
|
|
$rows = queryfx_all(
|
|
|
|
$conn,
|
|
|
|
'SELECT a.* FROM %T a %Q %Q %Q %Q',
|
|
|
|
$table->getTableName(),
|
|
|
|
$this->buildJoinClause($conn),
|
|
|
|
$this->buildWhereClause($conn),
|
|
|
|
$this->buildOrderClause($conn),
|
|
|
|
$this->buildLimitClause($conn));
|
|
|
|
|
|
|
|
return $table->loadAllFromArray($rows);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function willFilterPage(array $accounts) {
|
|
|
|
$query = id(new PhabricatorEdgeQuery())
|
|
|
|
->withSourcePHIDs(mpull($accounts, 'getPHID'))
|
|
|
|
->withEdgeTypes(array(PhabricatorEdgeConfig::TYPE_ACCOUNT_HAS_MEMBER));
|
|
|
|
$query->execute();
|
|
|
|
|
|
|
|
foreach ($accounts as $account) {
|
|
|
|
$member_phids = $query->getDestinationPHIDs(array($account->getPHID()));
|
|
|
|
$account->attachMemberPHIDs($member_phids);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $accounts;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function buildWhereClause(AphrontDatabaseConnection $conn) {
|
|
|
|
$where = array();
|
|
|
|
|
|
|
|
$where[] = $this->buildPagingClause($conn);
|
|
|
|
|
|
|
|
if ($this->ids) {
|
|
|
|
$where[] = qsprintf(
|
|
|
|
$conn,
|
|
|
|
'a.id IN (%Ld)',
|
|
|
|
$this->ids);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->phids) {
|
|
|
|
$where[] = qsprintf(
|
|
|
|
$conn,
|
|
|
|
'a.phid IN (%Ls)',
|
|
|
|
$this->phids);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->memberPHIDs) {
|
|
|
|
$where[] = qsprintf(
|
|
|
|
$conn,
|
|
|
|
'm.dst IN (%Ls)',
|
|
|
|
$this->memberPHIDs);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->formatWhereClause($where);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function buildJoinClause(AphrontDatabaseConnection $conn) {
|
|
|
|
$joins = array();
|
|
|
|
|
|
|
|
if ($this->memberPHIDs) {
|
|
|
|
$joins[] = qsprintf(
|
|
|
|
$conn,
|
|
|
|
'LEFT JOIN %T m ON a.phid = m.src AND m.type = %d',
|
|
|
|
PhabricatorEdgeConfig::TABLE_NAME_EDGE,
|
|
|
|
PhabricatorEdgeConfig::TYPE_ACCOUNT_HAS_MEMBER);
|
|
|
|
}
|
|
|
|
|
|
|
|
return implode(' ', $joins);
|
|
|
|
}
|
|
|
|
|
Lock policy queries to their applications
Summary:
While we mostly have reasonable effective object accessibility when you lock a user out of an application, it's primarily enforced at the controller level. Users can still, e.g., load the handles of objects they can't actually see. Instead, lock the queries to the applications so that you can, e.g., never load a revision if you don't have access to Differential.
This has several parts:
- For PolicyAware queries, provide an application class name method.
- If the query specifies a class name and the user doesn't have permission to use it, fail the entire query unconditionally.
- For handles, simplify query construction and count all the PHIDs as "restricted" so we get a UI full of "restricted" instead of "unknown" handles.
Test Plan:
- Added a unit test to verify I got all the class names right.
- Browsed around, logged in/out as a normal user with public policies on and off.
- Browsed around, logged in/out as a restricted user with public policies on and off. With restrictions, saw all traces of restricted apps removed or restricted.
Reviewers: btrahan
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D7367
2013-10-22 02:20:27 +02:00
|
|
|
|
|
|
|
public function getQueryApplicationClass() {
|
|
|
|
return 'PhabricatorApplicationPhortune';
|
|
|
|
}
|
|
|
|
|
Phortune v0
Summary:
Ref T2787. This does very little so far, but makes inroads on accounts and billing. This is mostly just modeled on what Stripe looks like. The objects are:
- **Account**: Has one or more authorized users, who can make manage the account. An example might be "Phacility", and the three of us would be able to manage it. A user may be associated with more than one account (e.g., a corporate account and a personal account) but the UI tries to simplify the common case of a single account.
- **Payment Method**: Something we can get sweet sweet money from; for now, a credit card registered with Stripe. Payment methods are associated with an account.
- **Product**: A good (one time charge) or service (recurring charge). This might be "t-shirt" or "enterprise plan" or "hourly support" or whatever else.
- **Purchase**: Represents a user purchasing a Product for an Account, using a Payment Method. e.g., you bought a shirt, or started a plan, or purchased support.
- **Charge**: Actual charges against payment methods. A Purchase can create more than one charge if it's a plan, or if the first charge fails and we re-bill.
This doesn't fully account for stuff like coupons/discounts yet but they should fit into the model without any issues.
This only implements `Account`, and that only partially.
Test Plan: {F37531}
Reviewers: chad, btrahan
Reviewed By: btrahan
CC: aran
Maniphest Tasks: T2787
Differential Revision: https://secure.phabricator.com/D5435
2013-03-28 17:10:34 +01:00
|
|
|
}
|