2015-05-27 19:30:08 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
final class PhabricatorOwnersPackageTransaction
|
|
|
|
extends PhabricatorApplicationTransaction {
|
|
|
|
|
|
|
|
const TYPE_NAME = 'owners.name';
|
|
|
|
const TYPE_PRIMARY = 'owners.primary';
|
|
|
|
const TYPE_OWNERS = 'owners.owners';
|
|
|
|
const TYPE_AUDITING = 'owners.auditing';
|
|
|
|
const TYPE_DESCRIPTION = 'owners.description';
|
Convert Owners paths to application transactions
Summary:
Ref T8320. Fixes T8317. Fixes T2831. Fixes T8073. Fixes T7127.
There was a bug with this line:
for ($ii = 0; $ii < count($paths); $ii++) {
...because the array may be sparse if there have been deletes, so `count($paths)` might be 3, but the real keys could be `1`, `5` and `6`. I think this was the primary issue behind T7127.
The old Editor did a lot of work to try to validate paths. When a path failed to validate, it silently discarded it. This was silly and pointless: it's incredibly bad UX; and it's totally fine if users saves "invalid" paths. This was likely the cause of T8317, and probably the cause of T8073.
T2831 I'm less sure about, but I can't reproduce it and I rewrote all the logic so I suspect it's gone.
This also records and shows edits, so if stuff does keep happening it should be more clear what's going on.
I removed some adjacent stuff:
- I removed the ability to delete packages. I'll add "disable" in a future diff, plus `bin/remove destroy`, like other objects. Getting rid of this now let me get rid of all the mail stuff.
- I removed "path validation" where packages would try to automatically update in response to commits. This doesn't necessarily make sense in Git/Mercurial, is sketchy, could easily have been the source of T2831, and seems generally complicated and not very valuable. We could maybe restore it some day, but I'd like to get Owners stable before trying to do crazy stuff like that.
Test Plan: {F437687}
Reviewers: chad, btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T8317, T8073, T7127, T2831, T8320
Differential Revision: https://secure.phabricator.com/D13032
2015-05-27 19:30:26 +02:00
|
|
|
const TYPE_PATHS = 'owners.paths';
|
2015-08-18 22:36:05 +02:00
|
|
|
const TYPE_STATUS = 'owners.status';
|
2015-05-27 19:30:08 +02:00
|
|
|
|
|
|
|
public function getApplicationName() {
|
|
|
|
return 'owners';
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getApplicationTransactionType() {
|
|
|
|
return PhabricatorOwnersPackagePHIDType::TYPECONST;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getRequiredHandlePHIDs() {
|
|
|
|
$phids = parent::getRequiredHandlePHIDs();
|
|
|
|
|
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case self::TYPE_OWNERS:
|
Implement basic ngram search for Owners Package names
Summary:
Ref T9979. This uses ngrams (specifically, trigrams) to build a reasonably efficient index for substring matching. Specifically, for a package like "Example", with ID 123, we store rows like this:
```
< ex, 123>
<exa, 123>
<xam, 123>
<amp, 123>
<mpl, 123>
<ple, 123>
<le , 123>
```
When the user searches for `exam`, we join this table for packages with tokens `exa` and `xam`. MySQL can do this a lot more efficiently than it can process a `LIKE "%exam%"` query against a huge table.
When the user searches for a one-letter or two-letter string, we only search the beginnings of words. This is probably what they want, the only thing we can do quickly, and a reasonable/expected behavior for typeaheads.
Test Plan:
- Ran storage upgrades and search indexer.
- Searched for stuff with "name contains".
- Used typehaead and got sensible results.
- Searched for `aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz` and saw only 16 joins.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9979
Differential Revision: https://secure.phabricator.com/D14846
2015-12-21 21:22:07 +01:00
|
|
|
if (!is_array($old)) {
|
|
|
|
$old = array();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!is_array($new)) {
|
|
|
|
$new = array();
|
|
|
|
}
|
|
|
|
|
2015-05-27 19:30:08 +02:00
|
|
|
$add = array_diff($new, $old);
|
|
|
|
foreach ($add as $phid) {
|
|
|
|
$phids[] = $phid;
|
|
|
|
}
|
|
|
|
$rem = array_diff($old, $new);
|
|
|
|
foreach ($rem as $phid) {
|
|
|
|
$phids[] = $phid;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $phids;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function shouldHide() {
|
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case self::TYPE_DESCRIPTION:
|
2015-12-18 19:14:37 +01:00
|
|
|
if ($old === null) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
2015-08-17 19:08:54 +02:00
|
|
|
case self::TYPE_PRIMARY:
|
|
|
|
// TODO: Eventually, remove these transactions entirely.
|
|
|
|
return true;
|
2015-05-27 19:30:08 +02:00
|
|
|
}
|
2015-12-18 19:14:37 +01:00
|
|
|
|
|
|
|
return parent::shouldHide();
|
2015-05-27 19:30:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getTitle() {
|
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
$author_phid = $this->getAuthorPHID();
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
2015-12-18 19:14:37 +01:00
|
|
|
case PhabricatorTransactions::TYPE_CREATE:
|
|
|
|
return pht(
|
|
|
|
'%s created this package.',
|
|
|
|
$this->renderHandleLink($author_phid));
|
2015-05-27 19:30:08 +02:00
|
|
|
case self::TYPE_NAME:
|
|
|
|
if ($old === null) {
|
|
|
|
return pht(
|
|
|
|
'%s created this package.',
|
|
|
|
$this->renderHandleLink($author_phid));
|
|
|
|
} else {
|
|
|
|
return pht(
|
|
|
|
'%s renamed this package from "%s" to "%s".',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
$old,
|
|
|
|
$new);
|
|
|
|
}
|
|
|
|
case self::TYPE_OWNERS:
|
|
|
|
$add = array_diff($new, $old);
|
|
|
|
$rem = array_diff($old, $new);
|
|
|
|
if ($add && !$rem) {
|
|
|
|
return pht(
|
|
|
|
'%s added %s owner(s): %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
count($add),
|
|
|
|
$this->renderHandleList($add));
|
|
|
|
} else if ($rem && !$add) {
|
|
|
|
return pht(
|
|
|
|
'%s removed %s owner(s): %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
count($rem),
|
|
|
|
$this->renderHandleList($rem));
|
|
|
|
} else {
|
|
|
|
return pht(
|
|
|
|
'%s changed %s package owner(s), added %s: %s; removed %s: %s.',
|
|
|
|
$this->renderHandleLink($author_phid),
|
|
|
|
count($add) + count($rem),
|
|
|
|
count($add),
|
|
|
|
$this->renderHandleList($add),
|
|
|
|
count($rem),
|
|
|
|
$this->renderHandleList($rem));
|
|
|
|
}
|
|
|
|
case self::TYPE_AUDITING:
|
|
|
|
if ($new) {
|
|
|
|
return pht(
|
|
|
|
'%s enabled auditing for this package.',
|
|
|
|
$this->renderHandleLink($author_phid));
|
|
|
|
} else {
|
|
|
|
return pht(
|
|
|
|
'%s disabled auditing for this package.',
|
|
|
|
$this->renderHandleLink($author_phid));
|
|
|
|
}
|
|
|
|
case self::TYPE_DESCRIPTION:
|
|
|
|
return pht(
|
|
|
|
'%s updated the description for this package.',
|
|
|
|
$this->renderHandleLink($author_phid));
|
Convert Owners paths to application transactions
Summary:
Ref T8320. Fixes T8317. Fixes T2831. Fixes T8073. Fixes T7127.
There was a bug with this line:
for ($ii = 0; $ii < count($paths); $ii++) {
...because the array may be sparse if there have been deletes, so `count($paths)` might be 3, but the real keys could be `1`, `5` and `6`. I think this was the primary issue behind T7127.
The old Editor did a lot of work to try to validate paths. When a path failed to validate, it silently discarded it. This was silly and pointless: it's incredibly bad UX; and it's totally fine if users saves "invalid" paths. This was likely the cause of T8317, and probably the cause of T8073.
T2831 I'm less sure about, but I can't reproduce it and I rewrote all the logic so I suspect it's gone.
This also records and shows edits, so if stuff does keep happening it should be more clear what's going on.
I removed some adjacent stuff:
- I removed the ability to delete packages. I'll add "disable" in a future diff, plus `bin/remove destroy`, like other objects. Getting rid of this now let me get rid of all the mail stuff.
- I removed "path validation" where packages would try to automatically update in response to commits. This doesn't necessarily make sense in Git/Mercurial, is sketchy, could easily have been the source of T2831, and seems generally complicated and not very valuable. We could maybe restore it some day, but I'd like to get Owners stable before trying to do crazy stuff like that.
Test Plan: {F437687}
Reviewers: chad, btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T8317, T8073, T7127, T2831, T8320
Differential Revision: https://secure.phabricator.com/D13032
2015-05-27 19:30:26 +02:00
|
|
|
case self::TYPE_PATHS:
|
|
|
|
// TODO: Flesh this out.
|
|
|
|
return pht(
|
|
|
|
'%s updated paths for this package.',
|
|
|
|
$this->renderHandleLink($author_phid));
|
2015-08-18 22:36:05 +02:00
|
|
|
case self::TYPE_STATUS:
|
|
|
|
if ($new == PhabricatorOwnersPackage::STATUS_ACTIVE) {
|
|
|
|
return pht(
|
|
|
|
'%s activated this package.',
|
|
|
|
$this->renderHandleLink($author_phid));
|
|
|
|
} else if ($new == PhabricatorOwnersPackage::STATUS_ARCHIVED) {
|
|
|
|
return pht(
|
|
|
|
'%s archived this package.',
|
|
|
|
$this->renderHandleLink($author_phid));
|
|
|
|
}
|
2015-05-27 19:30:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return parent::getTitle();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function hasChangeDetails() {
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case self::TYPE_DESCRIPTION:
|
|
|
|
return ($this->getOldValue() !== null);
|
Convert Owners paths to application transactions
Summary:
Ref T8320. Fixes T8317. Fixes T2831. Fixes T8073. Fixes T7127.
There was a bug with this line:
for ($ii = 0; $ii < count($paths); $ii++) {
...because the array may be sparse if there have been deletes, so `count($paths)` might be 3, but the real keys could be `1`, `5` and `6`. I think this was the primary issue behind T7127.
The old Editor did a lot of work to try to validate paths. When a path failed to validate, it silently discarded it. This was silly and pointless: it's incredibly bad UX; and it's totally fine if users saves "invalid" paths. This was likely the cause of T8317, and probably the cause of T8073.
T2831 I'm less sure about, but I can't reproduce it and I rewrote all the logic so I suspect it's gone.
This also records and shows edits, so if stuff does keep happening it should be more clear what's going on.
I removed some adjacent stuff:
- I removed the ability to delete packages. I'll add "disable" in a future diff, plus `bin/remove destroy`, like other objects. Getting rid of this now let me get rid of all the mail stuff.
- I removed "path validation" where packages would try to automatically update in response to commits. This doesn't necessarily make sense in Git/Mercurial, is sketchy, could easily have been the source of T2831, and seems generally complicated and not very valuable. We could maybe restore it some day, but I'd like to get Owners stable before trying to do crazy stuff like that.
Test Plan: {F437687}
Reviewers: chad, btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T8317, T8073, T7127, T2831, T8320
Differential Revision: https://secure.phabricator.com/D13032
2015-05-27 19:30:26 +02:00
|
|
|
case self::TYPE_PATHS:
|
|
|
|
return true;
|
2015-05-27 19:30:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return parent::hasChangeDetails();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function renderChangeDetails(PhabricatorUser $viewer) {
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case self::TYPE_DESCRIPTION:
|
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
|
|
|
|
return $this->renderTextCorpusChangeDetails(
|
|
|
|
$viewer,
|
|
|
|
$old,
|
|
|
|
$new);
|
Convert Owners paths to application transactions
Summary:
Ref T8320. Fixes T8317. Fixes T2831. Fixes T8073. Fixes T7127.
There was a bug with this line:
for ($ii = 0; $ii < count($paths); $ii++) {
...because the array may be sparse if there have been deletes, so `count($paths)` might be 3, but the real keys could be `1`, `5` and `6`. I think this was the primary issue behind T7127.
The old Editor did a lot of work to try to validate paths. When a path failed to validate, it silently discarded it. This was silly and pointless: it's incredibly bad UX; and it's totally fine if users saves "invalid" paths. This was likely the cause of T8317, and probably the cause of T8073.
T2831 I'm less sure about, but I can't reproduce it and I rewrote all the logic so I suspect it's gone.
This also records and shows edits, so if stuff does keep happening it should be more clear what's going on.
I removed some adjacent stuff:
- I removed the ability to delete packages. I'll add "disable" in a future diff, plus `bin/remove destroy`, like other objects. Getting rid of this now let me get rid of all the mail stuff.
- I removed "path validation" where packages would try to automatically update in response to commits. This doesn't necessarily make sense in Git/Mercurial, is sketchy, could easily have been the source of T2831, and seems generally complicated and not very valuable. We could maybe restore it some day, but I'd like to get Owners stable before trying to do crazy stuff like that.
Test Plan: {F437687}
Reviewers: chad, btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T8317, T8073, T7127, T2831, T8320
Differential Revision: https://secure.phabricator.com/D13032
2015-05-27 19:30:26 +02:00
|
|
|
case self::TYPE_PATHS:
|
|
|
|
$old = $this->getOldValue();
|
|
|
|
$new = $this->getNewValue();
|
|
|
|
|
|
|
|
$diffs = PhabricatorOwnersPath::getTransactionValueChanges($old, $new);
|
|
|
|
list($rem, $add) = $diffs;
|
|
|
|
|
|
|
|
$rows = array();
|
|
|
|
foreach ($rem as $ref) {
|
|
|
|
$rows[] = array(
|
|
|
|
'class' => 'diff-removed',
|
|
|
|
'change' => '-',
|
|
|
|
) + $ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($add as $ref) {
|
|
|
|
$rows[] = array(
|
|
|
|
'class' => 'diff-added',
|
|
|
|
'change' => '+',
|
|
|
|
) + $ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
$rowc = array();
|
|
|
|
foreach ($rows as $key => $row) {
|
|
|
|
$rowc[] = $row['class'];
|
|
|
|
$rows[$key] = array(
|
|
|
|
$row['change'],
|
|
|
|
$row['excluded'] ? pht('Exclude') : pht('Include'),
|
|
|
|
$viewer->renderHandle($row['repositoryPHID']),
|
|
|
|
$row['path'],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
$table = id(new AphrontTableView($rows))
|
|
|
|
->setRowClasses($rowc)
|
|
|
|
->setHeaders(
|
|
|
|
array(
|
|
|
|
null,
|
|
|
|
pht('Type'),
|
|
|
|
pht('Repository'),
|
|
|
|
pht('Path'),
|
|
|
|
))
|
|
|
|
->setColumnClasses(
|
|
|
|
array(
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
'wide',
|
|
|
|
));
|
|
|
|
|
|
|
|
return $table;
|
2015-05-27 19:30:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return parent::renderChangeDetails($viewer);
|
|
|
|
}
|
|
|
|
|
2015-11-16 18:53:01 +01:00
|
|
|
public function getRemarkupBlocks() {
|
|
|
|
$blocks = parent::getRemarkupBlocks();
|
|
|
|
|
|
|
|
switch ($this->getTransactionType()) {
|
|
|
|
case self::TYPE_DESCRIPTION:
|
|
|
|
$blocks[] = $this->getNewValue();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $blocks;
|
|
|
|
}
|
|
|
|
|
2015-05-27 19:30:08 +02:00
|
|
|
}
|