Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/owners/mail/PackageMail.php b/src/applications/owners/mail/PackageMail.php
index ec9dbbbe45..1ec79512d8 100644
--- a/src/applications/owners/mail/PackageMail.php
+++ b/src/applications/owners/mail/PackageMail.php
@@ -1,223 +1,222 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
abstract class PackageMail {
protected $package;
protected $handles;
protected $owners;
protected $paths;
protected $mailTo;
public function __construct($package) {
$this->package = $package;
}
abstract protected function getVerb();
abstract protected function isNewThread();
final protected function getPackage() {
return $this->package;
}
final protected function getHandles() {
return $this->handles;
}
final protected function getOwners() {
return $this->owners;
}
final protected function getPaths() {
return $this->paths;
}
final protected function getMailTo() {
return $this->mailTo;
}
final protected function renderPackageTitle() {
return $this->getPackage()->getName();
}
final protected function renderRepoSubSection($repository_phid, $paths) {
$handles = $this->getHandles();
$section = array();
$section[] = ' In repository '.$handles[$repository_phid]->getName().
' - '. PhabricatorEnv::getProductionURI($handles[$repository_phid]
->getURI());
foreach ($paths as $path => $ignored) {
$section[] = ' '.$path;
}
return implode("\n", $section);
}
protected function needSend() {
return true;
}
protected function loadData() {
$package = $this->getPackage();
$owners = $package->loadOwners();
$this->owners = $owners;
$owner_phids = mpull($owners, 'getUserPHID');
$primary_owner_phid = $package->getPrimaryOwnerPHID();
$mail_to = $owner_phids;
if (!in_array($primary_owner_phid, $owner_phids)) {
$mail_to[] = $primary_owner_phid;
}
$this->mailTo = $mail_to;
$paths = $package->loadPaths();
$this->paths = mgroup($paths, 'getRepositoryPHID', 'getPath');
- $phids = array_mergev(array(
+ $phids = array_merge(
$this->mailTo,
array($package->getActorPHID()),
- array_keys($this->paths),
- ));
+ array_keys($this->paths));
$this->handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
}
final protected function renderSummarySection() {
$package = $this->getPackage();
$handles = $this->getHandles();
$section = array();
$section[] = $handles[$package->getActorPHID()]->getName().' '.
strtolower($this->getVerb()).' '.$this->renderPackageTitle().'.';
$section[] = '';
$section[] = 'PACKAGE DETAIL';
$section[] = ' '.PhabricatorEnv::getProductionURI(
'/owners/package/'.$package->getID().'/');
return implode("\n", $section);
}
protected function renderDescriptionSection() {
return "PACKAGE DESCRIPTION\n".
' '.$this->getPackage()->getDescription();
}
protected function renderPrimaryOwnerSection() {
$handles = $this->getHandles();
return "PRIMARY OWNER\n".
' '.$handles[$this->getPackage()->getPrimaryOwnerPHID()]->getName();
}
protected function renderOwnersSection() {
$handles = $this->getHandles();
$owners = $this->getOwners();
if (!$owners) {
return null;
}
$owners = mpull($owners, 'getUserPHID');
$owners = array_select_keys($handles, $owners);
$owners = mpull($owners, 'getName');
return "OWNERS\n".
' '.implode(', ', $owners);
}
protected function renderAuditingEnabledSection() {
return "AUDITING ENABLED STATUS\n".
' '.($this->getPackage()->getAuditingEnabled() ? 'Enabled' : 'Disabled');
}
protected function renderPathsSection() {
$section = array();
$section[] = 'PATHS';
foreach ($this->paths as $repository_phid => $paths) {
$section[] = $this->renderRepoSubSection($repository_phid, $paths);
}
return implode("\n", $section);
}
final protected function renderBody() {
$body = array();
$body[] = $this->renderSummarySection();
$body[] = $this->renderDescriptionSection();
$body[] = $this->renderPrimaryOwnerSection();
$body[] = $this->renderOwnersSection();
$body[] = $this->renderAuditingEnabledSection();
$body[] = $this->renderPathsSection();
$body = array_filter($body);
return implode("\n\n", $body);
}
final public function send() {
$mails = $this->prepareMails();
foreach ($mails as $mail) {
$mail->saveAndSend();
}
}
final public function prepareMails() {
if (!$this->needSend()) {
return array();
}
$this->loadData();
$package = $this->getPackage();
$prefix = PhabricatorEnv::getEnvConfig('metamta.package.subject-prefix');
$verb = $this->getVerb();
$package_title = $this->renderPackageTitle();
$subject = trim("{$prefix} {$package_title}");
$vary_subject = trim("{$prefix} [{$verb}] {$package_title}");
$threading = $this->getMailThreading();
list($thread_id, $thread_topic) = $threading;
$template = id(new PhabricatorMetaMTAMail())
->setSubject($subject)
->setVarySubject($vary_subject)
->setFrom($package->getActorPHID())
->setThreadID($thread_id, $this->isNewThread())
->addHeader('Thread-Topic', $thread_topic)
->setRelatedPHID($package->getPHID())
->setIsBulk(true)
->setBody($this->renderBody());
$reply_handler = $this->newReplyHandler();
$mails = $reply_handler->multiplexMail(
$template,
array_select_keys($this->getHandles(), $this->getMailTo()),
array());
return $mails;
}
private function getMailThreading() {
return array(
'package-'.$this->getPackage()->getPHID(),
'package '.$this->getPackage()->getPHID(),
);
}
private function newReplyHandler() {
$reply_handler = PhabricatorEnv::newObjectFromConfig(
'metamta.package.reply-handler');
$reply_handler->setMailReceiver($this->getPackage());
return $reply_handler;
}
}
diff --git a/src/applications/owners/mail/PackageModifyMail.php b/src/applications/owners/mail/PackageModifyMail.php
index b5fd890ecd..7f38698c72 100644
--- a/src/applications/owners/mail/PackageModifyMail.php
+++ b/src/applications/owners/mail/PackageModifyMail.php
@@ -1,175 +1,174 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PackageModifyMail extends PackageMail {
protected $addOwners;
protected $removeOwners;
protected $allOwners;
protected $touchedRepos;
protected $addPaths;
protected $removePaths;
public function __construct(
PhabricatorOwnersPackage $package,
$add_owners,
$remove_owners,
$all_owners,
$touched_repos,
$add_paths,
$remove_paths) {
$this->package = $package;
$this->addOwners = $add_owners;
$this->removeOwners = $remove_owners;
$this->allOwners = $all_owners;
$this->touchedRepos = $touched_repos;
$this->addPaths = $add_paths;
$this->removePaths = $remove_paths;
}
protected function getVerb() {
return 'Modified';
}
protected function isNewThread() {
return false;
}
protected function needSend() {
$package = $this->getPackage();
if ($package->getOldPrimaryOwnerPHID() !== $package->getPrimaryOwnerPHID()
|| $package->getOldAuditingEnabled() != $package->getAuditingEnabled()
|| $this->addOwners
|| $this->removeOwners
|| $this->addPaths
|| $this->removePaths) {
return true;
} else {
return false;
}
}
protected function loadData() {
$this->mailTo = $this->allOwners;
- $phids = array_mergev(array(
+ $phids = array_merge(
$this->allOwners,
$this->touchedRepos,
array(
$this->getPackage()->getActorPHID(),
- ),
- ));
+ ));
$this->handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
}
protected function renderDescriptionSection() {
return null;
}
protected function renderPrimaryOwnerSection() {
$package = $this->getPackage();
$handles = $this->getHandles();
$old_primary_owner_phid = $package->getOldPrimaryOwnerPHID();
$primary_owner_phid = $package->getPrimaryOwnerPHID();
if ($old_primary_owner_phid == $primary_owner_phid) {
return null;
}
$section = array();
$section[] = 'PRIMARY OWNER CHANGE';
$section[] = ' Old owner: ' .
$handles[$old_primary_owner_phid]->getName();
$section[] = ' New owner: ' .
$handles[$primary_owner_phid]->getName();
$section[] = '';
return implode("\n", $section);
}
protected function renderOwnersSection() {
$section = array();
$add_owners = $this->addOwners;
$remove_owners = $this->removeOwners;
$handles = $this->getHandles();
if ($add_owners) {
$add_owners = array_select_keys($handles, $add_owners);
$add_owners = mpull($add_owners, 'getName');
$section[] = 'ADDED OWNERS';
$section[] = ' '.implode(', ', $add_owners);
}
if ($remove_owners) {
if ($add_owners) {
$section[] = '';
}
$remove_owners = array_select_keys($handles, $remove_owners);
$remove_owners = mpull($remove_owners, 'getName');
$section[] = 'REMOVED OWNERS';
$section[] = ' '.implode(', ', $remove_owners);
}
if ($section) {
return implode("\n", $section);
} else {
return null;
}
}
protected function renderAuditingEnabledSection() {
$package = $this->getPackage();
$old_auditing_enabled = $package->getOldAuditingEnabled();
$auditing_enabled = $package->getAuditingEnabled();
if ($old_auditing_enabled == $auditing_enabled) {
return null;
}
$section = array();
$section[] = 'AUDITING ENABLED STATUS CHANGE';
$section[] = ' Old value: '.
($old_auditing_enabled ? 'Enabled' : 'Disabled');
$section[] = ' New value: '.
($auditing_enabled ? 'Enabled' : 'Disabled');
return implode("\n", $section);
}
protected function renderPathsSection() {
$section = array();
if ($this->addPaths) {
$section[] = 'ADDED PATHS';
foreach ($this->addPaths as $repository_phid => $paths) {
$section[] = $this->renderRepoSubSection($repository_phid, $paths);
}
}
if ($this->removePaths) {
if ($this->addPaths) {
$section[] = '';
}
$section[] = 'REMOVED PATHS';
foreach ($this->removePaths as $repository_phid => $paths) {
$section[] = $this->renderRepoSubSection($repository_phid, $paths);
}
}
return implode("\n", $section);
}
}
diff --git a/src/applications/owners/storage/PhabricatorOwnersPackage.php b/src/applications/owners/storage/PhabricatorOwnersPackage.php
index 2fa5e579a5..39f45c14c3 100644
--- a/src/applications/owners/storage/PhabricatorOwnersPackage.php
+++ b/src/applications/owners/storage/PhabricatorOwnersPackage.php
@@ -1,335 +1,335 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorOwnersPackage extends PhabricatorOwnersDAO {
protected $phid;
protected $name;
protected $auditingEnabled;
protected $description;
protected $primaryOwnerPHID;
private $unsavedOwners;
private $unsavedPaths;
private $actorPHID;
private $oldPrimaryOwnerPHID;
private $oldAuditingEnabled;
public function getConfiguration() {
return array(
// This information is better available from the history table.
self::CONFIG_TIMESTAMPS => false,
self::CONFIG_AUX_PHID => true,
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID('OPKG');
}
public function attachUnsavedOwners(array $owners) {
$this->unsavedOwners = $owners;
return $this;
}
public function attachUnsavedPaths(array $paths) {
$this->unsavedPaths = $paths;
return $this;
}
public function attachActorPHID($actor_phid) {
$this->actorPHID = $actor_phid;
return $this;
}
public function getActorPHID() {
return $this->actorPHID;
}
public function attachOldPrimaryOwnerPHID($old_primary) {
$this->oldPrimaryOwnerPHID = $old_primary;
return $this;
}
public function getOldPrimaryOwnerPHID() {
return $this->oldPrimaryOwnerPHID;
}
public function attachOldAuditingEnabled($auditing_enabled) {
$this->oldAuditingEnabled = $auditing_enabled;
return $this;
}
public function getOldAuditingEnabled() {
return $this->oldAuditingEnabled;
}
public function loadOwners() {
if (!$this->getID()) {
return array();
}
return id(new PhabricatorOwnersOwner())->loadAllWhere(
'packageID = %d',
$this->getID());
}
public function loadPaths() {
if (!$this->getID()) {
return array();
}
return id(new PhabricatorOwnersPath())->loadAllWhere(
'packageID = %d',
$this->getID());
}
public static function loadAffectedPackages(
PhabricatorRepository $repository,
array $paths) {
if (!$paths) {
return array();
}
$fragments = array(
'/' => true,
);
foreach ($paths as $path) {
$fragments += self::splitPath($path);
}
return self::loadPackagesForPaths($repository, array_keys($fragments));
}
public static function loadOwningPackages($repository, $path) {
if (empty($path)) {
return array();
}
$fragments = self::splitPath($path);
return self::loadPackagesForPaths($repository, array_keys($fragments), 1);
}
private static function loadPackagesForPaths(
PhabricatorRepository $repository,
array $paths,
$limit = 0) {
$package = new PhabricatorOwnersPackage();
$path = new PhabricatorOwnersPath();
$conn = $package->establishConnection('r');
$repository_clause = qsprintf($conn, 'AND p.repositoryPHID = %s',
$repository->getPHID());
$limit_clause = '';
if (!empty($limit)) {
$limit_clause = qsprintf($conn, 'LIMIT %d', $limit);
}
$data = queryfx_all(
$conn,
'SELECT pkg.id FROM %T pkg JOIN %T p ON p.packageID = pkg.id
WHERE p.path IN (%Ls) %Q ORDER BY LENGTH(p.path) DESC %Q',
$package->getTableName(),
$path->getTableName(),
$paths,
$repository_clause,
$limit_clause);
$ids = ipull($data, 'id');
if (empty($ids)) {
return array();
}
$order = array();
foreach ($ids as $id) {
if (empty($order[$id])) {
$order[$id] = true;
}
}
$packages = $package->loadAllWhere('id in (%Ld)', array_keys($order));
$packages = array_select_keys($packages, array_keys($order));
return $packages;
}
public function save() {
if ($this->getID()) {
$is_new = false;
} else {
$is_new = true;
}
$this->openTransaction();
$ret = parent::save();
$add_owners = array();
$remove_owners = array();
$all_owners = array();
if ($this->unsavedOwners) {
$new_owners = array_fill_keys($this->unsavedOwners, true);
$cur_owners = array();
foreach ($this->loadOwners() as $owner) {
if (empty($new_owners[$owner->getUserPHID()])) {
$remove_owners[$owner->getUserPHID()] = true;
$owner->delete();
continue;
}
$cur_owners[$owner->getUserPHID()] = true;
}
$add_owners = array_diff_key($new_owners, $cur_owners);
- $all_owners = array_mergev(array(
+ $all_owners = array_merge(
array($this->getPrimaryOwnerPHID() => true),
$new_owners,
- $remove_owners));
+ $remove_owners);
foreach ($add_owners as $phid => $ignored) {
$owner = new PhabricatorOwnersOwner();
$owner->setPackageID($this->getID());
$owner->setUserPHID($phid);
$owner->save();
}
unset($this->unsavedOwners);
}
$add_paths = array();
$remove_paths = array();
$touched_repos = array();
if ($this->unsavedPaths) {
$new_paths = igroup($this->unsavedPaths, 'repositoryPHID', 'path');
$cur_paths = $this->loadPaths();
foreach ($cur_paths as $key => $path) {
if (empty($new_paths[$path->getRepositoryPHID()][$path->getPath()])) {
$touched_repos[$path->getRepositoryPHID()] = true;
$remove_paths[$path->getRepositoryPHID()][$path->getPath()] = true;
$path->delete();
unset($cur_paths[$key]);
}
}
$cur_paths = mgroup($cur_paths, 'getRepositoryPHID', 'getPath');
foreach ($new_paths as $repository_phid => $paths) {
// get repository object for path validation
$repository = id(new PhabricatorRepository())->loadOneWhere(
'phid = %s',
$repository_phid);
if (!$repository) {
continue;
}
foreach ($paths as $path => $ignored) {
$path = ltrim($path, '/');
// build query to validate path
$drequest = DiffusionRequest::newFromDictionary(
array(
'repository' => $repository,
'path' => $path,
));
$query = DiffusionBrowseQuery::newFromDiffusionRequest($drequest);
$query->needValidityOnly(true);
$valid = $query->loadPaths();
$is_directory = true;
if (!$valid) {
switch ($query->getReasonForEmptyResultSet()) {
case DiffusionBrowseQuery::REASON_IS_FILE:
$valid = true;
$is_directory = false;
break;
case DiffusionBrowseQuery::REASON_IS_EMPTY:
$valid = true;
break;
}
}
if ($is_directory && substr($path, -1) != '/') {
$path .= '/';
}
if (substr($path, 0, 1) != '/') {
$path = '/'.$path;
}
if (empty($cur_paths[$repository_phid][$path]) && $valid) {
$touched_repos[$repository_phid] = true;
$add_paths[$repository_phid][$path] = true;
$obj = new PhabricatorOwnersPath();
$obj->setPackageID($this->getID());
$obj->setRepositoryPHID($repository_phid);
$obj->setPath($path);
$obj->save();
}
}
}
unset($this->unsavedPaths);
}
$this->saveTransaction();
if ($is_new) {
$mail = new PackageCreateMail($this);
} else {
$mail = new PackageModifyMail(
$this,
array_keys($add_owners),
array_keys($remove_owners),
array_keys($all_owners),
array_keys($touched_repos),
$add_paths,
$remove_paths);
}
$mail->send();
return $ret;
}
public function delete() {
$mails = id(new PackageDeleteMail($this))->prepareMails();
$this->openTransaction();
foreach ($this->loadOwners() as $owner) {
$owner->delete();
}
foreach ($this->loadPaths() as $path) {
$path->delete();
}
$ret = parent::delete();
$this->saveTransaction();
foreach ($mails as $mail) {
$mail->saveAndSend();
}
return $ret;
}
private static function splitPath($path) {
$result = array();
$trailing_slash = preg_match('@/$@', $path) ? '/' : '';
$path = trim($path, '/');
$parts = explode('/', $path);
while (count($parts)) {
$result['/'.implode('/', $parts).$trailing_slash] = true;
$trailing_slash = '/';
array_pop($parts);
}
return $result;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Nov 6, 5:19 AM (13 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
321651
Default Alt Text
(21 KB)

Event Timeline