1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 14:00:56 +01:00

Merge branch 'master' of github.com:facebook/phabricator into new

This commit is contained in:
mgummelt 2011-07-07 15:30:20 -07:00
commit 81e3ec5998
182 changed files with 3141 additions and 566 deletions

View file

@ -12,6 +12,7 @@
"diffusion" : "Diffusion (Repository Browser)",
"maniphest" : "Maniphest (Task Tracking)",
"herald" : "Herald (Notifications)",
"conduit" : "Conduit (Phabricator HTTP API)",
"celerity" : "Celerity (CSS/JS Management)",
"aphront" : "Aphront (Web Stack)",
"console" : "DarkConsole (Debugging Console)",

View file

@ -2,6 +2,11 @@ This is not a complete list of changes, just of API or workflow changes that may
break existing installs. Newer changes are listed at the top. If you pull new
changes and things stop working, check here first!
June 29 2011 - Maniphest project indexes
Old Maniphest tasks will not appear in project filter views until you run
"scripts/search/reindex_maniphest.php" to build indexes. New tasks will have
their indexes built automatically.
May 31 2011 - Javelin submodule moved
The externals/javelin submodule location has moved. If you have an older
checkout of Phabricator, you may need to edit .git/config to point at

View file

@ -190,6 +190,27 @@ return array(
// Prefix prepended to mail sent by Differential.
'metamta.differential.subject-prefix' => '[Differential]',
// By default, Phabricator generates unique reply-to addresses and sends a
// separate email to each recipient when you enable reply handling. This is
// more secure than using "From" to establish user identity, but can mean
// users may receive multiple emails when they are on mailing lists. Instead,
// you can use a single, non-unique reply to address and authenticate users
// based on the "From" address by setting this to 'true'. This trades away
// a little bit of security for convenience, but it's reasonable in many
// installs. Object interactions are still protected using hashes in the
// single public email address, so objects can not be replied to blindly.
'metamta.public-replies' => false,
// You can configure an email address like "bugs@phabricator.example.com"
// which will automatically create Maniphest tasks when users send email
// to it. This relies on the "From" address to authenticate users, so it is
// is not completely secure. To set this up, enter a complete email
// address like "bugs@phabricator.example.com" and then configure mail to
// that address so it routed to Phabricator (if you've already configured
// reply handlers, you're probably already done). See "Configuring Inbound
// Email" in the documentation for more information.
'metamta.maniphest.public-create-email' => null,
// -- Auth ------------------------------------------------------------------ //
@ -294,14 +315,6 @@ return array(
// behalf, silencing the warning.
'phabricator.timezone' => null,
// Phabricator can highlight PHP by default, but if you want syntax
// highlighting for other languages you should install the python package
// 'Pygments', make sure the 'pygmentize' script is available in the
// $PATH of the webserver, and then enable this.
'pygments.enabled' => false,
// -- Files ----------------------------------------------------------------- //
// Lists which uploaded file types may be viewed in the browser. If a file
@ -372,6 +385,37 @@ return array(
// silly (but sort of awesome).
'remarkup.enable-embedded-youtube' => false,
// -- Garbage Collection ---------------------------------------------------- //
// Phabricator generates various logs and caches in the database which can
// be garbage collected after a while to make the total data size more
// manageable. To run garbage collection, launch a
// PhabricatorGarbageCollector daemon.
// Since the GC daemon can issue large writes and table scans, you may want to
// run it only during off hours or make sure it is scheduled so it doesn't
// overlap with backups. This determines when the daemon can start running
// each day.
'gcdaemon.run-at' => '12 AM',
// How many seconds after 'gcdaemon.run-at' the daemon may collect garbage
// for. By default it runs continuously, but you can set it to run for a
// limited period of time. For instance, if you do backups at 3 AM, you might
// run garbage collection for an hour beforehand. This is not a high-precision
// limit so you may want to leave some room for the GC to actually stop, and
// if you set it to something like 3 seconds you're on your own.
'gcdaemon.run-for' => 24 * 60 * 60,
// These 'ttl' keys configure how much old data the GC daemon keeps around.
// Objects older than the ttl will be collected. Set any value to 0 to store
// data indefinitely.
'gcdaemon.ttl.herald-transcripts' => 30 * (24 * 60 * 60),
'gcdaemon.ttl.daemon-logs' => 7 * (24 * 60 * 60),
'gcdaemon.ttl.differential-render-cache' => 7 * (24 * 60 * 60),
// -- Customization --------------------------------------------------------- //
// Paths to additional phutil libraries to load.
@ -405,4 +449,60 @@ return array(
// settings are the defaults.)
'celerity.force-disk-reads' => false,
// -- Pygments ------------------------------------------------------------ //
// Phabricator can highlight PHP by default, but if you want syntax
// highlighting for other languages you should install the python package
// 'Pygments', make sure the 'pygmentize' script is available in the
// $PATH of the webserver, and then enable this.
'pygments.enabled' => false,
// In places that we display a dropdown to syntax-highlight code,
// this is where that list is defined.
// Syntax is 'lexer-name' => 'Display Name',
'pygments.dropdown-choices' => array(
'apacheconf' => 'Apache Configuration',
'bash' => 'Bash Scripting',
'brainfuck' => 'Brainf*ck',
'c' => 'C',
'cpp' => 'C++',
'css' => 'CSS',
'diff' => 'Diff',
'django' => 'Django Templating',
'erb' => 'Embedded Ruby/ERB',
'erlang' => 'Erlang',
'html' => 'HTML',
'infer' => 'Infer from title (extension)',
'java' => 'Java',
'js' => 'Javascript',
'mysql' => 'MySQL',
'perl' => 'Perl',
'php' => 'PHP',
'text' => 'Plain Text',
'python' => 'Python',
// TODO: 'remarkup' => 'Remarkup',
'ruby' => 'Ruby',
'xml' => 'XML',
),
'pygments.dropdown-default' => 'infer',
// This is an override list of regular expressions which allows you to choose
// what language files are highlighted as. If your projects have certain rules
// about filenames or use unusual or ambiguous language extensions, you can
// create a mapping here. This is an ordered dictionary of regular expressions
// which will be tested against the filename. They should map to either an
// explicit language as a string value, or a numeric index into the captured
// groups as an integer.
'syntax.filemap' => array(
// Example: Treat all '*.xyz' files as PHP.
// '@\\.xyz$@' => 'php',
// Example: Treat 'httpd.conf' as 'apacheconf'.
// '@/httpd\\.conf$@' => 'apacheconf',
// Example: Treat all '*.x.bak' file as '.x'. NOTE: we map to capturing
// group 1 by specifying the mapping as "1".
// '@\\.([^.]+)\\.bak$@' => 1,
),
);

2
externals/javelin vendored

@ -1 +1 @@
Subproject commit c727216edfb2527d14e1047656986f0cb8f694f9
Subproject commit c6bf95cd19da7179c10220a858f4662139b6c3a0

View file

@ -0,0 +1,6 @@
CREATE TABLE phabricator_maniphest.maniphest_taskproject (
taskPHID varchar(64) BINARY NOT NULL,
projectPHID varchar(64) BINARY NOT NULL,
PRIMARY KEY (projectPHID, taskPHID),
UNIQUE KEY (taskPHID, projectPHID)
);

View file

@ -0,0 +1,2 @@
ALTER TABLE phabricator_pastebin.pastebin_paste
ADD COLUMN language VARCHAR(64) NOT NULL;

View file

@ -0,0 +1,21 @@
CREATE DATABASE phabricator_feed;
CREATE TABLE phabricator_feed.feed_storydata (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARCHAR(64) BINARY NOT NULL,
UNIQUE KEY (phid),
chronologicalKey BIGINT UNSIGNED NOT NULL,
UNIQUE KEY (chronologicalKey),
storyType varchar(64) NOT NULL,
storyData LONGBLOB NOT NULL,
authorPHID varchar(64) BINARY NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL
);
CREATE TABLE phabricator_feed.feed_storyreference (
objectPHID varchar(64) BINARY NOT NULL,
chronologicalKey BIGINT UNSIGNED NOT NULL,
UNIQUE KEY (objectPHID, chronologicalKey),
KEY (chronologicalKey)
);

View file

@ -0,0 +1,6 @@
CREATE TABLE phabricator_maniphest.maniphest_tasksubscriber (
taskPHID varchar(64) BINARY NOT NULL,
subscriberPHID varchar(64) BINARY NOT NULL,
PRIMARY KEY (subscriberPHID, taskPHID),
UNIQUE KEY (taskPHID, subscriberPHID)
);

View file

@ -65,10 +65,10 @@ then
# (it tries to pull in php 5.1 stuff) ...
echo "Adding EPEL repo, for git."
$SUDO rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
YUMCOMMAND="$SUDO yum install httpd git php53 php53-cli php53-mysql php53-process php53-devel php53-gd gcc wget make pcre-devel"
YUMCOMMAND="$SUDO yum install httpd git php53 php53-cli php53-mysql php53-process php53-devel php53-gd gcc wget make pcre-devel mysql-server"
else
# RHEL 6+ defaults with php 5.3
YUMCOMMAND="$SUDO yum install httpd git php php-cli php-mysql php-process php-devel php-gd php-pecl-apc php-pecl-json"
YUMCOMMAND="$SUDO yum install httpd git php php-cli php-mysql php-process php-devel php-gd php-pecl-apc php-pecl-json mysql-server"
fi
echo "Dropping to yum to install dependencies..."

View file

@ -0,0 +1,63 @@
#!/bin/sh
set -e
set -x
# This is an example script for updating Phabricator, similar to the one used to
# update <https://secure.phabricator.com/>. It might not work perfectly on your
# system, but hopefully it should be easy to adapt.
# NOTE: This script assumes you are running it from a directory which contains
# arcanist/, libphutil/, phabricator/, and possibly diviner/.
ROOT=`pwd` # You can hard-code the path here instead.
### UPDATE WORKING COPIES ######################################################
if [ -e $ROOT/diviner ]
then
(cd $ROOT/diviner && git pull)
fi
(cd $ROOT/libphutil && git pull)
(cd $ROOT/arcanist && git pull)
(cd $ROOT/phabricator && git pull && git submodule update --init)
### GENERATE DOCUMENTATION #####################################################
# This generates documentation if you have diviner/ checked out. You generally
# don't need to do this unless you're contributing to Phabricator and want to
# preview some of the amazing documentation you've just written.
if [ -e $ROOT/diviner ]
then
(cd $ROOT/diviner && $ROOT/diviner/bin/diviner .)
(cd $ROOT/libphutil && $ROOT/diviner/bin/diviner .)
(cd $ROOT/arcanist && $ROOT/diviner/bin/diviner .)
(cd $ROOT/phabricator && $ROOT/diviner/bin/diviner .)
fi
### CYCLE APACHE AND DAEMONS ###################################################
# Stop Apache. Depening on what system you're running, you may need to use
# 'apachectl' or something else to cycle apache.
sudo /etc/init.d/httpd stop
# Stop daemons.
$ROOT/phabricator/bin/phd stop
# Upgrade the database schema.
$ROOT/phabricator/scripts/sql/upgrade_schema.php -f
# Restart apache.
sudo /etc/init.d/httpd start
# Restart daemons. Customize this to start whatever daemons you're running on
# your system.
# $ROOT/phabricator/bin/phd repository-launch-master
# $ROOT/phabricator/bin/phd launch metamta
# $ROOT/phabricator/bin/phd launch garbagecollector
# $ROOT/phabricator/bin/phd launch 4 taskmaster
# $ROOT/phabricator/bin/phd launch ircbot /config/bot.json

View file

@ -0,0 +1,33 @@
#!/usr/bin/env php
<?php
/*
* Copyright 2011 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.
*/
$root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/__init_script__.php';
require_once $root.'/scripts/__init_env__.php';
ini_set('memory_limit', -1);
$tasks = id(new ManiphestTask())->loadAll();
echo "Updating relationships for ".count($tasks)." tasks";
foreach ($tasks as $task) {
ManiphestTaskProject::updateTaskProjects($task);
ManiphestTaskSubscriber::updateTaskSubscribers($task);
echo '.';
}
echo "\nDone.\n";

View file

@ -258,7 +258,7 @@ celerity_register_resource_map(array(
),
'herald-rule-editor' =>
array(
'uri' => '/res/402e94d2/rsrc/js/application/herald/HeraldRuleEditor.js',
'uri' => '/res/ba957508/rsrc/js/application/herald/HeraldRuleEditor.js',
'type' => 'js',
'requires' =>
array(
@ -285,17 +285,18 @@ celerity_register_resource_map(array(
),
0 =>
array(
'uri' => '/res/39de799e/rsrc/js/javelin/docs/Base.js',
'uri' => '/res/1da00bfe/rsrc/js/javelin/lib/__tests__/URI.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
0 => 'javelin-uri',
1 => 'javelin-php-serializer',
),
'disk' => '/rsrc/js/javelin/docs/Base.js',
'disk' => '/rsrc/js/javelin/lib/__tests__/URI.js',
),
'javelin-behavior' =>
array(
'uri' => '/res/3c772c64/rsrc/js/javelin/lib/behavior.js',
'uri' => '/res/b28adfa1/rsrc/js/javelin/lib/behavior.js',
'type' => 'js',
'requires' =>
array(
@ -613,7 +614,7 @@ celerity_register_resource_map(array(
),
'javelin-behavior-phabricator-keyboard-shortcuts' =>
array(
'uri' => '/res/7aed0604/rsrc/js/application/core/behavior-keyboard-shortcuts.js',
'uri' => '/res/94b009e2/rsrc/js/application/core/behavior-keyboard-shortcuts.js',
'type' => 'js',
'requires' =>
array(
@ -665,7 +666,7 @@ celerity_register_resource_map(array(
),
'javelin-dom' =>
array(
'uri' => '/res/43e9e2de/rsrc/js/javelin/lib/DOM.js',
'uri' => '/res/34e7f2b5/rsrc/js/javelin/lib/DOM.js',
'type' => 'js',
'requires' =>
array(
@ -689,7 +690,7 @@ celerity_register_resource_map(array(
),
'javelin-install' =>
array(
'uri' => '/res/f4d0e147/rsrc/js/javelin/core/install.js',
'uri' => '/res/b6692f42/rsrc/js/javelin/core/install.js',
'type' => 'js',
'requires' =>
array(
@ -700,7 +701,7 @@ celerity_register_resource_map(array(
),
'javelin-json' =>
array(
'uri' => '/res/1c4e3f6a/rsrc/js/javelin/lib/JSON.js',
'uri' => '/res/f23dbfbd/rsrc/js/javelin/lib/JSON.js',
'type' => 'js',
'requires' =>
array(
@ -711,7 +712,7 @@ celerity_register_resource_map(array(
),
'javelin-magical-init' =>
array(
'uri' => '/res/92e7f37e/rsrc/js/javelin/core/init.js',
'uri' => '/res/6a069362/rsrc/js/javelin/core/init.js',
'type' => 'js',
'requires' =>
array(
@ -732,7 +733,7 @@ celerity_register_resource_map(array(
),
'javelin-request' =>
array(
'uri' => '/res/1ed0d596/rsrc/js/javelin/lib/Request.js',
'uri' => '/res/786bfe6f/rsrc/js/javelin/lib/Request.js',
'type' => 'js',
'requires' =>
array(
@ -740,12 +741,13 @@ celerity_register_resource_map(array(
1 => 'javelin-stratcom',
2 => 'javelin-util',
3 => 'javelin-behavior',
4 => 'javelin-json',
),
'disk' => '/rsrc/js/javelin/lib/Request.js',
),
'javelin-stratcom' =>
array(
'uri' => '/res/9e7eb62b/rsrc/js/javelin/core/Stratcom.js',
'uri' => '/res/d6cf4631/rsrc/js/javelin/core/Stratcom.js',
'type' => 'js',
'requires' =>
array(
@ -758,7 +760,7 @@ celerity_register_resource_map(array(
),
'javelin-tokenizer' =>
array(
'uri' => '/res/83787676/rsrc/js/javelin/lib/control/tokenizer/Tokenizer.js',
'uri' => '/res/c2dbba74/rsrc/js/javelin/lib/control/tokenizer/Tokenizer.js',
'type' => 'js',
'requires' =>
array(
@ -771,7 +773,7 @@ celerity_register_resource_map(array(
),
'javelin-typeahead' =>
array(
'uri' => '/res/ae18ee16/rsrc/js/javelin/lib/control/typeahead/Typeahead.js',
'uri' => '/res/354d32f1/rsrc/js/javelin/lib/control/typeahead/Typeahead.js',
'type' => 'js',
'requires' =>
array(
@ -782,6 +784,18 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/js/javelin/lib/control/typeahead/Typeahead.js',
),
'javelin-typeahead-composite-source' =>
array(
'uri' => '/res/9873d21c/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-typeahead-source',
2 => 'javelin-util',
),
'disk' => '/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js',
),
'javelin-typeahead-normalizer' =>
array(
'uri' => '/res/a5d60e3c/rsrc/js/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js',
@ -794,7 +808,7 @@ celerity_register_resource_map(array(
),
'javelin-typeahead-ondemand-source' =>
array(
'uri' => '/res/0015bbf5/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js',
'uri' => '/res/b2e527e4/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js',
'type' => 'js',
'requires' =>
array(
@ -808,7 +822,7 @@ celerity_register_resource_map(array(
),
'javelin-typeahead-preloaded-source' =>
array(
'uri' => '/res/863a173c/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js',
'uri' => '/res/f3c1e7c7/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js',
'type' => 'js',
'requires' =>
array(
@ -822,7 +836,7 @@ celerity_register_resource_map(array(
),
'javelin-typeahead-source' =>
array(
'uri' => '/res/58518dde/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadSource.js',
'uri' => '/res/8a3aa262/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadSource.js',
'type' => 'js',
'requires' =>
array(
@ -835,7 +849,7 @@ celerity_register_resource_map(array(
),
'javelin-uri' =>
array(
'uri' => '/res/70c9d32b/rsrc/js/javelin/lib/URI.js',
'uri' => '/res/1c0ead43/rsrc/js/javelin/lib/URI.js',
'type' => 'js',
'requires' =>
array(
@ -847,7 +861,7 @@ celerity_register_resource_map(array(
),
'javelin-util' =>
array(
'uri' => '/res/be43fdba/rsrc/js/javelin/core/util.js',
'uri' => '/res/725cc90d/rsrc/js/javelin/core/util.js',
'type' => 'js',
'requires' =>
array(
@ -856,7 +870,7 @@ celerity_register_resource_map(array(
),
'javelin-vector' =>
array(
'uri' => '/res/cd4721c4/rsrc/js/javelin/lib/Vector.js',
'uri' => '/res/50535cb8/rsrc/js/javelin/lib/Vector.js',
'type' => 'js',
'requires' =>
array(
@ -867,7 +881,7 @@ celerity_register_resource_map(array(
),
'javelin-workflow' =>
array(
'uri' => '/res/28a267b3/rsrc/js/javelin/lib/Workflow.js',
'uri' => '/res/91a04640/rsrc/js/javelin/lib/Workflow.js',
'type' => 'js',
'requires' =>
array(
@ -1066,7 +1080,7 @@ celerity_register_resource_map(array(
),
'phabricator-search-results-css' =>
array(
'uri' => '/res/9a9eeaf2/rsrc/css/application/search/search-results.css',
'uri' => '/res/f8a86e27/rsrc/css/application/search/search-results.css',
'type' => 'css',
'requires' =>
array(
@ -1125,7 +1139,7 @@ celerity_register_resource_map(array(
'uri' => '/res/pkg/03ef179e/diffusion.pkg.css',
'type' => 'css',
),
'2892314d' =>
'25f94e94' =>
array (
'name' => 'typeahead.pkg.js',
'symbols' =>
@ -1138,7 +1152,26 @@ celerity_register_resource_map(array(
5 => 'javelin-tokenizer',
6 => 'javelin-behavior-aphront-basic-tokenizer',
),
'uri' => '/res/pkg/2892314d/typeahead.pkg.js',
'uri' => '/res/pkg/25f94e94/typeahead.pkg.js',
'type' => 'js',
),
'307df223' =>
array (
'name' => 'javelin.pkg.js',
'symbols' =>
array (
0 => 'javelin-util',
1 => 'javelin-install',
2 => 'javelin-event',
3 => 'javelin-stratcom',
4 => 'javelin-behavior',
5 => 'javelin-request',
6 => 'javelin-vector',
7 => 'javelin-dom',
8 => 'javelin-json',
9 => 'javelin-uri',
),
'uri' => '/res/pkg/307df223/javelin.pkg.js',
'type' => 'js',
),
55967526 =>
@ -1182,40 +1215,7 @@ celerity_register_resource_map(array(
'uri' => '/res/pkg/8e9024dc/core.pkg.css',
'type' => 'css',
),
'da416e1c' =>
array (
'name' => 'differential.pkg.js',
'symbols' =>
array (
0 => 'javelin-behavior-differential-feedback-preview',
1 => 'javelin-behavior-differential-edit-inline-comments',
2 => 'javelin-behavior-differential-populate',
3 => 'javelin-behavior-differential-show-more',
4 => 'javelin-behavior-differential-diff-radios',
),
'uri' => '/res/pkg/da416e1c/differential.pkg.js',
'type' => 'js',
),
'db95a6d0' =>
array (
'name' => 'javelin.pkg.js',
'symbols' =>
array (
0 => 'javelin-util',
1 => 'javelin-install',
2 => 'javelin-event',
3 => 'javelin-stratcom',
4 => 'javelin-behavior',
5 => 'javelin-request',
6 => 'javelin-vector',
7 => 'javelin-dom',
8 => 'javelin-json',
9 => 'javelin-uri',
),
'uri' => '/res/pkg/db95a6d0/javelin.pkg.js',
'type' => 'js',
),
'f1d27e2a' =>
'd0713563' =>
array (
'name' => 'workflow.pkg.js',
'symbols' =>
@ -1228,7 +1228,21 @@ celerity_register_resource_map(array(
5 => 'phabricator-keyboard-shortcut',
6 => 'javelin-behavior-phabricator-keyboard-shortcuts',
),
'uri' => '/res/pkg/f1d27e2a/workflow.pkg.js',
'uri' => '/res/pkg/d0713563/workflow.pkg.js',
'type' => 'js',
),
'da416e1c' =>
array (
'name' => 'differential.pkg.js',
'symbols' =>
array (
0 => 'javelin-behavior-differential-feedback-preview',
1 => 'javelin-behavior-differential-edit-inline-comments',
2 => 'javelin-behavior-differential-populate',
3 => 'javelin-behavior-differential-show-more',
4 => 'javelin-behavior-differential-diff-radios',
),
'uri' => '/res/pkg/da416e1c/differential.pkg.js',
'type' => 'js',
),
),
@ -1252,38 +1266,38 @@ celerity_register_resource_map(array(
'differential-revision-history-css' => '55967526',
'differential-table-of-contents-css' => '55967526',
'diffusion-commit-view-css' => '03ef179e',
'javelin-behavior' => 'db95a6d0',
'javelin-behavior-aphront-basic-tokenizer' => '2892314d',
'javelin-behavior-aphront-form-disable-on-submit' => 'f1d27e2a',
'javelin-behavior' => '307df223',
'javelin-behavior-aphront-basic-tokenizer' => '25f94e94',
'javelin-behavior-aphront-form-disable-on-submit' => 'd0713563',
'javelin-behavior-differential-diff-radios' => 'da416e1c',
'javelin-behavior-differential-edit-inline-comments' => 'da416e1c',
'javelin-behavior-differential-feedback-preview' => 'da416e1c',
'javelin-behavior-differential-populate' => 'da416e1c',
'javelin-behavior-differential-show-more' => 'da416e1c',
'javelin-behavior-phabricator-keyboard-shortcuts' => 'f1d27e2a',
'javelin-behavior-workflow' => 'f1d27e2a',
'javelin-dom' => 'db95a6d0',
'javelin-event' => 'db95a6d0',
'javelin-install' => 'db95a6d0',
'javelin-json' => 'db95a6d0',
'javelin-mask' => 'f1d27e2a',
'javelin-request' => 'db95a6d0',
'javelin-stratcom' => 'db95a6d0',
'javelin-tokenizer' => '2892314d',
'javelin-typeahead' => '2892314d',
'javelin-typeahead-normalizer' => '2892314d',
'javelin-typeahead-ondemand-source' => '2892314d',
'javelin-typeahead-preloaded-source' => '2892314d',
'javelin-typeahead-source' => '2892314d',
'javelin-uri' => 'db95a6d0',
'javelin-util' => 'db95a6d0',
'javelin-vector' => 'db95a6d0',
'javelin-workflow' => 'f1d27e2a',
'javelin-behavior-phabricator-keyboard-shortcuts' => 'd0713563',
'javelin-behavior-workflow' => 'd0713563',
'javelin-dom' => '307df223',
'javelin-event' => '307df223',
'javelin-install' => '307df223',
'javelin-json' => '307df223',
'javelin-mask' => 'd0713563',
'javelin-request' => '307df223',
'javelin-stratcom' => '307df223',
'javelin-tokenizer' => '25f94e94',
'javelin-typeahead' => '25f94e94',
'javelin-typeahead-normalizer' => '25f94e94',
'javelin-typeahead-ondemand-source' => '25f94e94',
'javelin-typeahead-preloaded-source' => '25f94e94',
'javelin-typeahead-source' => '25f94e94',
'javelin-uri' => '307df223',
'javelin-util' => '307df223',
'javelin-vector' => '307df223',
'javelin-workflow' => 'd0713563',
'phabricator-core-buttons-css' => '8e9024dc',
'phabricator-core-css' => '8e9024dc',
'phabricator-directory-css' => '8e9024dc',
'phabricator-keyboard-shortcut' => 'f1d27e2a',
'phabricator-keyboard-shortcut-manager' => 'f1d27e2a',
'phabricator-keyboard-shortcut' => 'd0713563',
'phabricator-keyboard-shortcut-manager' => 'd0713563',
'phabricator-remarkup-css' => '8e9024dc',
'phabricator-standard-page-view' => '8e9024dc',
'syntax-highlighting-css' => '8e9024dc',

View file

@ -103,6 +103,7 @@ phutil_register_library_map(array(
'ConduitAPI_differential_updateunitresults_Method' => 'applications/conduit/method/differential/updateunitresults',
'ConduitAPI_diffusion_getcommits_Method' => 'applications/conduit/method/diffusion/getcommits',
'ConduitAPI_diffusion_getrecentcommitsbypath_Method' => 'applications/conduit/method/diffusion/getrecentcommitsbypath',
'ConduitAPI_feed_publish_Method' => 'applications/conduit/method/feed/publish',
'ConduitAPI_file_download_Method' => 'applications/conduit/method/file/download',
'ConduitAPI_file_upload_Method' => 'applications/conduit/method/file/upload',
'ConduitAPI_maniphest_info_Method' => 'applications/conduit/method/maniphest/info',
@ -261,6 +262,7 @@ phutil_register_library_map(array(
'LiskIsolationTestCase' => 'storage/lisk/dao/__tests__',
'LiskIsolationTestDAO' => 'storage/lisk/dao/__tests__',
'LiskIsolationTestDAOException' => 'storage/lisk/dao/__tests__',
'ManiphestConstants' => 'applications/maniphest/constants/base',
'ManiphestController' => 'applications/maniphest/controller/base',
'ManiphestDAO' => 'applications/maniphest/storage/base',
'ManiphestReplyHandler' => 'applications/maniphest/replyhandler',
@ -272,7 +274,10 @@ phutil_register_library_map(array(
'ManiphestTaskListView' => 'applications/maniphest/view/tasklist',
'ManiphestTaskOwner' => 'applications/maniphest/constants/owner',
'ManiphestTaskPriority' => 'applications/maniphest/constants/priority',
'ManiphestTaskProject' => 'applications/maniphest/storage/taskproject',
'ManiphestTaskQuery' => 'applications/maniphest/query',
'ManiphestTaskStatus' => 'applications/maniphest/constants/status',
'ManiphestTaskSubscriber' => 'applications/maniphest/storage/subscriber',
'ManiphestTaskSummaryView' => 'applications/maniphest/view/tasksummary',
'ManiphestTransaction' => 'applications/maniphest/storage/transaction',
'ManiphestTransactionDetailView' => 'applications/maniphest/view/transactiondetail',
@ -281,6 +286,7 @@ phutil_register_library_map(array(
'ManiphestTransactionPreviewController' => 'applications/maniphest/controller/transactionpreview',
'ManiphestTransactionSaveController' => 'applications/maniphest/controller/transactionsave',
'ManiphestTransactionType' => 'applications/maniphest/constants/transactiontype',
'ManiphestView' => 'applications/maniphest/view/base',
'Phabricator404Controller' => 'applications/base/controller/404',
'PhabricatorAuthController' => 'applications/auth/controller/base',
'PhabricatorConduitAPIController' => 'applications/conduit/controller/api',
@ -332,6 +338,17 @@ phutil_register_library_map(array(
'PhabricatorEmailLoginController' => 'applications/auth/controller/email',
'PhabricatorEmailTokenController' => 'applications/auth/controller/emailtoken',
'PhabricatorEnv' => 'infrastructure/env',
'PhabricatorFeedController' => 'applications/feed/controller/base',
'PhabricatorFeedDAO' => 'applications/feed/storage/base',
'PhabricatorFeedQuery' => 'applications/feed/query',
'PhabricatorFeedStory' => 'applications/feed/story/base',
'PhabricatorFeedStoryData' => 'applications/feed/storage/story',
'PhabricatorFeedStoryPublisher' => 'applications/feed/publisher',
'PhabricatorFeedStoryReference' => 'applications/feed/storage/storyreference',
'PhabricatorFeedStoryUnknown' => 'applications/feed/story/unknown',
'PhabricatorFeedStoryView' => 'applications/feed/view/story',
'PhabricatorFeedStreamController' => 'applications/feed/controller/stream',
'PhabricatorFeedView' => 'applications/feed/view/base',
'PhabricatorFile' => 'applications/files/storage/file',
'PhabricatorFileController' => 'applications/files/controller/base',
'PhabricatorFileDAO' => 'applications/files/storage/base',
@ -348,6 +365,7 @@ phutil_register_library_map(array(
'PhabricatorFileURI' => 'applications/files/uri',
'PhabricatorFileUploadController' => 'applications/files/controller/upload',
'PhabricatorFileViewController' => 'applications/files/controller/view',
'PhabricatorGarbageCollectorDaemon' => 'infrastructure/daemon/garbagecollector',
'PhabricatorGoodForNothingWorker' => 'infrastructure/daemon/workers/worker/goodfornothing',
'PhabricatorHandleObjectSelectorDataView' => 'applications/phid/handle/view/selector',
'PhabricatorHelpController' => 'applications/help/controller/base',
@ -439,7 +457,6 @@ phutil_register_library_map(array(
'PhabricatorProjectProfileController' => 'applications/project/controller/profile',
'PhabricatorProjectProfileEditController' => 'applications/project/controller/profileedit',
'PhabricatorProjectStatus' => 'applications/project/constants/status',
'PhabricatorProjectTransactionSearch' => 'applications/project/transactions/search',
'PhabricatorRedirectController' => 'applications/base/controller/redirect',
'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/remarkup/markuprule/differential',
'PhabricatorRemarkupRuleDiffusion' => 'infrastructure/markup/remarkup/markuprule/diffusion',
@ -506,6 +523,7 @@ phutil_register_library_map(array(
'PhabricatorSetup' => 'infrastructure/setup',
'PhabricatorStandardPageView' => 'view/page/standard',
'PhabricatorStatusController' => 'applications/status/base',
'PhabricatorSyntaxHighlighter' => 'applications/markup/syntax',
'PhabricatorTaskmasterDaemon' => 'infrastructure/daemon/workers/taskmaster',
'PhabricatorTestCase' => 'infrastructure/testing/testcase',
'PhabricatorTimelineCursor' => 'infrastructure/daemon/timeline/storage/cursor',
@ -656,6 +674,7 @@ phutil_register_library_map(array(
'ConduitAPI_differential_updateunitresults_Method' => 'ConduitAPIMethod',
'ConduitAPI_diffusion_getcommits_Method' => 'ConduitAPIMethod',
'ConduitAPI_diffusion_getrecentcommitsbypath_Method' => 'ConduitAPIMethod',
'ConduitAPI_feed_publish_Method' => 'ConduitAPIMethod',
'ConduitAPI_file_download_Method' => 'ConduitAPIMethod',
'ConduitAPI_file_upload_Method' => 'ConduitAPIMethod',
'ConduitAPI_maniphest_info_Method' => 'ConduitAPIMethod',
@ -764,13 +783,20 @@ phutil_register_library_map(array(
'ManiphestTaskDetailController' => 'ManiphestController',
'ManiphestTaskEditController' => 'ManiphestController',
'ManiphestTaskListController' => 'ManiphestController',
'ManiphestTaskListView' => 'AphrontView',
'ManiphestTaskSummaryView' => 'AphrontView',
'ManiphestTaskListView' => 'ManiphestView',
'ManiphestTaskOwner' => 'ManiphestConstants',
'ManiphestTaskPriority' => 'ManiphestConstants',
'ManiphestTaskProject' => 'ManiphestDAO',
'ManiphestTaskStatus' => 'ManiphestConstants',
'ManiphestTaskSubscriber' => 'ManiphestDAO',
'ManiphestTaskSummaryView' => 'ManiphestView',
'ManiphestTransaction' => 'ManiphestDAO',
'ManiphestTransactionDetailView' => 'AphrontView',
'ManiphestTransactionListView' => 'AphrontView',
'ManiphestTransactionDetailView' => 'ManiphestView',
'ManiphestTransactionListView' => 'ManiphestView',
'ManiphestTransactionPreviewController' => 'ManiphestController',
'ManiphestTransactionSaveController' => 'ManiphestController',
'ManiphestTransactionType' => 'ManiphestConstants',
'ManiphestView' => 'AphrontView',
'Phabricator404Controller' => 'PhabricatorController',
'PhabricatorAuthController' => 'PhabricatorController',
'PhabricatorConduitAPIController' => 'PhabricatorConduitController',
@ -819,6 +845,14 @@ phutil_register_library_map(array(
'PhabricatorEditPreferencesController' => 'PhabricatorPreferencesController',
'PhabricatorEmailLoginController' => 'PhabricatorAuthController',
'PhabricatorEmailTokenController' => 'PhabricatorAuthController',
'PhabricatorFeedController' => 'PhabricatorController',
'PhabricatorFeedDAO' => 'PhabricatorLiskDAO',
'PhabricatorFeedStoryData' => 'PhabricatorFeedDAO',
'PhabricatorFeedStoryReference' => 'PhabricatorFeedDAO',
'PhabricatorFeedStoryUnknown' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryView' => 'PhabricatorFeedView',
'PhabricatorFeedStreamController' => 'PhabricatorFeedController',
'PhabricatorFeedView' => 'AphrontView',
'PhabricatorFile' => 'PhabricatorFileDAO',
'PhabricatorFileController' => 'PhabricatorController',
'PhabricatorFileDAO' => 'PhabricatorLiskDAO',
@ -834,6 +868,7 @@ phutil_register_library_map(array(
'PhabricatorFileTransformController' => 'PhabricatorFileController',
'PhabricatorFileUploadController' => 'PhabricatorFileController',
'PhabricatorFileViewController' => 'PhabricatorFileController',
'PhabricatorGarbageCollectorDaemon' => 'PhabricatorDaemon',
'PhabricatorGoodForNothingWorker' => 'PhabricatorWorker',
'PhabricatorHelpController' => 'PhabricatorController',
'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController',

View file

@ -330,6 +330,10 @@ class AphrontDefaultApplicationConfiguration
'delete/(?P<id>\d+)/$'
=> 'PhabricatorCountdownDeleteController'
),
'/feed/' => array(
'$' => 'PhabricatorFeedStreamController',
),
);
}

View file

@ -31,10 +31,17 @@ class PhabricatorLoginController extends PhabricatorAuthController {
}
$next_uri = $this->getRequest()->getPath();
if ($next_uri == '/login/') {
$next_uri = null;
$request->setCookie('next_uri', $next_uri);
if ($next_uri == '/login/' && !$request->isFormPost()) {
// The user went straight to /login/, so presumably they want to go
// to the dashboard upon logging in. Because, you know, that's logical.
// And people are logical. Sometimes... Fine, no they're not.
// We check for POST here because getPath() would get reset to /login/.
$request->setCookie('next_uri', '/');
}
// Always use $request->getCookie('next_uri', '/') after the above.
$password_auth = PhabricatorEnv::getEnvConfig('auth.password-auth-enabled');
$forms = array();
@ -66,7 +73,7 @@ class PhabricatorLoginController extends PhabricatorAuthController {
$request->setCookie('phsid', $session_key);
return id(new AphrontRedirectResponse())
->setURI('/');
->setURI($request->getCookie('next_uri', '/'));
} else {
$log = PhabricatorUserLog::newLog(
null,
@ -93,7 +100,6 @@ class PhabricatorLoginController extends PhabricatorAuthController {
$form
->setUser($request->getUser())
->setAction('/login/')
->addHiddenInput('next', $next_uri)
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Username/Email')
@ -115,8 +121,6 @@ class PhabricatorLoginController extends PhabricatorAuthController {
$forms['Phabricator Login'] = $form;
}
$oauth_state = $next_uri;
$providers = array(
PhabricatorOAuthProvider::PROVIDER_FACEBOOK,
PhabricatorOAuthProvider::PROVIDER_GITHUB,
@ -160,7 +164,6 @@ class PhabricatorLoginController extends PhabricatorAuthController {
->addHiddenInput('client_id', $client_id)
->addHiddenInput('redirect_uri', $redirect_uri)
->addHiddenInput('scope', $minimum_scope)
->addHiddenInput('state', $oauth_state)
->setUser($request->getUser())
->setMethod('GET')
->appendChild(

View file

@ -135,12 +135,7 @@ class PhabricatorOAuthLoginController extends PhabricatorAuthController {
->setURI('/settings/page/'.$provider_key.'/');
}
$next_uri = '/';
if ($this->oauthState) {
// Make sure a blind redirect to evil.com is impossible.
$uri = new PhutilURI($this->oauthState);
$next_uri = $uri->getPath();
}
$next_uri = $request->getCookie('next_uri', '/');
// Login with known auth.
@ -158,6 +153,7 @@ class PhabricatorOAuthLoginController extends PhabricatorAuthController {
$request->setCookie('phusr', $known_user->getUsername());
$request->setCookie('phsid', $session_key);
$request->clearCookie('next_uri');
return id(new AphrontRedirectResponse())
->setURI($next_uri);
}

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class PhabricatorConduitAPIController
extends PhabricatorConduitController {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
abstract class PhabricatorConduitController extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class PhabricatorConduitConsoleController
extends PhabricatorConduitController {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class PhabricatorConduitLogController extends PhabricatorConduitController {
public function processRequest() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class PhabricatorConduitTokenController extends PhabricatorConduitController {
public function processRequest() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
abstract class ConduitAPIMethod {
abstract public function getMethodDescription();
@ -63,4 +66,29 @@ abstract class ConduitAPIMethod {
return str_replace('_', '.', $method_fragment);
}
protected function validateHost($host) {
if (!$host) {
// If the client doesn't send a host key, don't complain. We should in
// the future, but this change isn't severe enough to bump the protocol
// version.
// TODO: Remove this once the protocol version gets bumped past 2 (i.e.,
// require the host key be present and valid).
return;
}
$host = new PhutilURI($host);
$host->setPath('/');
$host = (string)$host;
$self = PhabricatorEnv::getProductionURI('/');
if ($self !== $host) {
throw new Exception(
"Your client is connecting to this install as '{$host}', but it is ".
"configured as '{$self}'. The client and server must use the exact ".
"same URI to identify the install. Edit your .arcconfig or ".
"phabricator/conf so they agree on the URI for the install.");
}
}
}

View file

@ -6,6 +6,9 @@
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phutil', 'parser/uri');
phutil_require_module('phutil', 'utils');

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_conduit_connect_Method extends ConduitAPIMethod {
public function shouldRequireAuthentication() {
@ -34,6 +37,7 @@ class ConduitAPI_conduit_connect_Method extends ConduitAPIMethod {
'user' => 'optional string',
'authToken' => 'optional int',
'authSignature' => 'optional string',
'host' => 'required string',
);
}
@ -67,6 +71,8 @@ class ConduitAPI_conduit_connect_Method extends ConduitAPIMethod {
protected function execute(ConduitAPIRequest $request) {
$this->validateHost($request->getValue('host'));
$client = $request->getValue('client');
$client_version = (int)$request->getValue('clientVersion');
$client_description = (string)$request->getValue('clientDescription');

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_conduit_getcertificate_Method extends ConduitAPIMethod {
public function shouldRequireAuthentication() {
@ -29,6 +32,7 @@ class ConduitAPI_conduit_getcertificate_Method extends ConduitAPIMethod {
public function defineParamTypes() {
return array(
'token' => 'required string',
'host' => 'required string',
);
}
@ -46,6 +50,7 @@ class ConduitAPI_conduit_getcertificate_Method extends ConduitAPIMethod {
}
protected function execute(ConduitAPIRequest $request) {
$this->validateHost($request->getValue('host'));
$failed_attempts = PhabricatorUserLog::loadRecentEventsFromThisIP(
PhabricatorUserLog::ACTION_CONDUIT_CERTIFICATE_FAILURE,

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_conduit_ping_Method extends ConduitAPIMethod {
public function shouldRequireAuthentication() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_daemon_launched_Method extends ConduitAPIMethod {
public function shouldRequireAuthentication() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_daemon_log_Method extends ConduitAPIMethod {
public function shouldRequireAuthentication() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_differential_creatediff_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_differential_createrevision_Method extends ConduitAPIMethod {
public function getMethodDescription() {
@ -26,7 +29,6 @@ class ConduitAPI_differential_createrevision_Method extends ConduitAPIMethod {
return array(
'diffid' => 'required diffid',
'fields' => 'required dict',
'user' => 'required guid',
);
}
@ -51,7 +53,7 @@ class ConduitAPI_differential_createrevision_Method extends ConduitAPIMethod {
$revision = DifferentialRevisionEditor::newRevisionFromConduitWithDiff(
$fields,
$diff,
$request->getValue('user')); // TODO: Should be authoritative
$request->getUser()->getPHID());
return array(
'revisionid' => $revision->getID(),

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_differential_find_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_differential_getalldiffs_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_differential_getcommitmessage_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_differential_getcommitpaths_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_differential_getdiff_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_differential_getrevision_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_differential_getrevisionfeedback_Method
extends ConduitAPIMethod {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_differential_markcommitted_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_differential_parsecommitmessage_Method
extends ConduitAPIMethod {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_differential_setdiffproperty_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_differential_updaterevision_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,8 +16,12 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_differential_updatetaskrevisionassoc_Method
extends ConduitAPIMethod {
public function getMethodDescription() {
return "Given a task together with its original and new associated ".
"revisions, update the revisions for their attached_tasks.";

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_differential_updateunitresults_Method
extends ConduitAPIMethod {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_diffusion_getcommits_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_diffusion_getrecentcommitsbypath_Method
extends ConduitAPIMethod {

View file

@ -0,0 +1,65 @@
<?php
/*
* Copyright 2011 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.
*/
/**
* @group conduit
*/
class ConduitAPI_feed_publish_Method extends ConduitAPIMethod {
public function getMethodDescription() {
return "(UNSTABLE!!!) Publish a story to the feed.";
}
public function defineParamTypes() {
return array(
'type' => 'required string',
'data' => 'required dict',
'time' => 'optional int',
);
}
public function defineErrorTypes() {
return array(
);
}
public function defineReturnType() {
return 'nonempty phid';
}
protected function execute(ConduitAPIRequest $request) {
$type = $request->getValue('type');
$data = $request->getValue('data');
$time = $request->getValue('time');
$author_phid = $request->getUser()->getPHID();
$phids = array($author_phid);
$publisher = new PhabricatorFeedStoryPublisher();
$publisher->setStoryType($type);
$publisher->setStoryData($data);
$publisher->setStoryTime($time);
$publisher->setRelatedPHIDs($phids);
$publisher->setStoryAuthorPHID($author_phid);
$data = $publisher->publish();
return $data->getPHID();
}
}

View file

@ -0,0 +1,13 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/conduit/method/base');
phutil_require_module('phabricator', 'applications/feed/publisher');
phutil_require_source('ConduitAPI_feed_publish_Method.php');

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_file_download_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_file_upload_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_maniphest_info_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_paste_info_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_path_getowners_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_user_find_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPI_user_whoami_Method extends ConduitAPIMethod {
public function getMethodDescription() {

View file

@ -16,5 +16,8 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitException extends Exception {
}

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class ConduitAPIRequest {
protected $params;

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
abstract class PhabricatorConduitDAO extends PhabricatorLiskDAO {
public function getApplicationName() {

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class PhabricatorConduitConnectionLog extends PhabricatorConduitDAO {
protected $client;

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class PhabricatorConduitMethodCallLog extends PhabricatorConduitDAO {
protected $connectionID;

View file

@ -16,6 +16,9 @@
* limitations under the License.
*/
/**
* @group conduit
*/
class PhabricatorConduitCertificateToken extends PhabricatorConduitDAO {
protected $userPHID;

View file

@ -43,11 +43,46 @@ final class PhabricatorDaemonLogEventsView extends AphrontView {
}
foreach ($this->events as $event) {
// Limit display log size. If a daemon gets stuck in an output loop this
// page can be like >100MB if we don't truncate stuff. Try to do cheap
// line-based truncation first, and fall back to expensive UTF-8 character
// truncation if that doesn't get things short enough.
$message = $event->getMessage();
$more_lines = null;
$more_chars = null;
$line_limit = 12;
if (substr_count($message, "\n") > $line_limit) {
$message = explode("\n", $message);
$more_lines = count($message) - $line_limit;
$message = array_slice($message, 0, $line_limit);
$message = implode("\n", $message);
}
$char_limit = 8192;
if (strlen($message) > $char_limit) {
$message = phutil_utf8v($message);
$more_chars = count($message) - $char_limit;
$message = array_slice($message, 0, $char_limit);
$message = implode('', $message);
}
$more = null;
if ($more_chars) {
$more = number_format($more_chars);
$more = "\n<... {$more} more characters ...>";
} else if ($more_lines) {
$more = number_format($more_lines);
$more = "\n<... {$more} more lines ...>";
}
$row = array(
phutil_escape_html($event->getLogType()),
phabricator_date($event->getEpoch(), $this->user),
phabricator_time($event->getEpoch(), $this->user),
str_replace("\n", '<br />', phutil_escape_html($event->getMessage())),
str_replace("\n", '<br />', phutil_escape_html($message.$more)),
);
if ($this->combinedLog) {

View file

@ -11,6 +11,7 @@ phutil_require_module('phabricator', 'view/control/table');
phutil_require_module('phabricator', 'view/utils');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorDaemonLogEventsView.php');

View file

@ -57,6 +57,7 @@ class DifferentialRevisionEditController extends DifferentialController {
$e_title = true;
$e_testplan = true;
$e_reviewers = null;
$errors = array();
$revision->loadRelationships();
@ -71,17 +72,22 @@ class DifferentialRevisionEditController extends DifferentialController {
if (!strlen(trim($revision->getTitle()))) {
$errors[] = 'You must provide a title.';
$e_title = 'Required';
} else {
$e_title = null;
}
if (!strlen(trim($revision->getTestPlan()))) {
$errors[] = 'You must provide a test plan.';
$e_testplan = 'Required';
} else {
$e_testplan = null;
}
$user_phid = $request->getUser()->getPHID();
if (in_array($user_phid, $request->getArr('reviewers'))) {
$errors[] = 'You may not review your own revision.';
$e_reviewers = 'Invalid';
}
if (!$errors) {
@ -172,6 +178,7 @@ class DifferentialRevisionEditController extends DifferentialController {
->setLabel('Reviewers')
->setName('reviewers')
->setDatasource('/typeahead/common/users/')
->setError($e_reviewers)
->setValue($reviewer_map))
->appendChild(
id(new AphrontFormTokenizerControl())

View file

@ -319,4 +319,12 @@ EOTEXT;
return $this->heraldTranscriptURI;
}
protected function renderHandleList(array $handles, array $phids) {
$names = array();
foreach ($phids as $phid) {
$names[] = $handles[$phid]->getName();
}
return implode(', ', $names);
}
}

View file

@ -30,6 +30,7 @@ class DifferentialCCWelcomeMail extends DifferentialReviewRequestMail {
$body = array();
$body[] = "{$actor} added you to the CC list for the revision \"{$name}\".";
$body[] = $this->renderReviewersLine();
$body[] = null;
$body[] = $this->renderReviewRequestBody();

View file

@ -71,6 +71,32 @@ class DifferentialCommentMail extends DifferentialMail {
$body = array();
$body[] = "{$actor} has {$verb} the revision \"{$name}\".";
// If the commented added reviewers or CCs, list them explicitly.
$meta = $comment->getMetadata();
$m_reviewers = idx(
$meta,
DifferentialComment::METADATA_ADDED_REVIEWERS,
array());
$m_cc = idx(
$meta,
DifferentialComment::METADATA_ADDED_CCS,
array());
$load = array_merge($m_reviewers, $m_cc);
if ($load) {
$handles = id(new PhabricatorObjectHandleData($load))->loadHandles();
if ($m_reviewers) {
$body[] = 'Added Reviewers: '.$this->renderHandleList(
$handles,
$m_reviewers);
}
if ($m_cc) {
$body[] = 'Added CCs: '.$this->renderHandleList(
$handles,
$m_cc);
}
}
$body[] = null;
$content = $comment->getContent();

View file

@ -9,6 +9,7 @@
phutil_require_module('phabricator', 'applications/differential/constants/action');
phutil_require_module('phabricator', 'applications/differential/constants/revisionstatus');
phutil_require_module('phabricator', 'applications/differential/mail/base');
phutil_require_module('phabricator', 'applications/differential/storage/comment');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'infrastructure/env');

View file

@ -58,6 +58,7 @@ class DifferentialNewDiffMail extends DifferentialReviewRequestMail {
} else {
$body[] = "{$actor} updated the revision \"{$name}\".";
}
$body[] = $this->renderReviewersLine();
$body[] = null;
$body[] = $this->renderReviewRequestBody();

View file

@ -39,6 +39,12 @@ abstract class DifferentialReviewRequestMail extends DifferentialMail {
$this->setChangesets($changesets);
}
protected function renderReviewersLine() {
$reviewers = $this->getRevision()->getReviewers();
$handles = id(new PhabricatorObjectHandleData($reviewers))->loadHandles();
return 'Reviewers: '.$this->renderHandleList($handles, $reviewers);
}
protected function renderReviewRequestBody() {
$revision = $this->getRevision();

View file

@ -7,6 +7,9 @@
phutil_require_module('phabricator', 'applications/differential/mail/base');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phutil', 'utils');
phutil_require_source('DifferentialReviewRequestMail.php');

View file

@ -27,7 +27,6 @@ class DifferentialChangesetParser {
protected $parsedHunk = false;
protected $filename = null;
protected $filetype = null;
protected $missingOld = array();
protected $missingNew = array();
@ -161,10 +160,7 @@ class DifferentialChangesetParser {
public function setFilename($filename) {
$this->filename = $filename;
if (strpos($filename, '.', 1) !== false) {
$parts = explode('.', $filename);
$this->filetype = end($parts);
}
return $this;
}
public function setHandles(array $handles) {
@ -341,6 +337,21 @@ class DifferentialChangesetParser {
switch ($this->whitespaceMode) {
case self::WHITESPACE_IGNORE_TRAILING:
if (rtrim($o_desc['text']) == rtrim($n_desc['text'])) {
if ($o_desc['type']) {
// If we're converting this into an unchanged line because of
// a trailing whitespace difference, mark it as a whitespace
// change so we can show "This file was modified only by
// adding or removing trailing whitespace." instead of
// "This file was not modified.".
$whitelines = true;
}
$similar = true;
}
break;
default:
// In this case, the lines are similar if there is no change type
// (that is, just trust the diff algorithm).
if (!$o_desc['type']) {
$similar = true;
}
break;
@ -349,7 +360,6 @@ class DifferentialChangesetParser {
$o_desc['type'] = null;
$n_desc['type'] = null;
$skip_intra[count($old)] = true;
$whitelines = true;
} else {
$changed = true;
}
@ -700,7 +710,7 @@ class DifferentialChangesetParser {
foreach ($vector as $ii => $char) {
$result[] = $char;
if (isset($break_here[$ii])) {
$result[] = "<span class=\"over-the-line\">!</span><br />";
$result[] = "<span class=\"over-the-line\">\xE2\xAC\x85</span><br />";
}
}
@ -709,7 +719,7 @@ class DifferentialChangesetParser {
protected function getHighlightFuture($corpus) {
return $this->highlightEngine->getHighlightFuture(
$this->filetype,
$this->highlightEngine->getLanguageFromFilename($this->filename),
$corpus);
}
@ -744,24 +754,38 @@ class DifferentialChangesetParser {
$changeset->getFileType() == DifferentialChangeType::FILE_SYMLINK) {
if ($skip_cache || !$this->loadCache()) {
$ignore_all = ($this->whitespaceMode == self::WHITESPACE_IGNORE_ALL);
// The "ignore all whitespace" algorithm depends on rediffing the
// files, and we currently need complete representations of both
// files to do anything reasonable. If we only have parts of the files,
// don't use the "ignore all" algorithm.
$can_use_ignore_all = true;
$hunks = $changeset->getHunks();
if (count($hunks) !== 1) {
$can_use_ignore_all = false;
} else {
$first_hunk = reset($hunks);
if ($first_hunk->getOldOffset() != 1 ||
$first_hunk->getNewOffset() != 1) {
$can_use_ignore_all = false;
if ($ignore_all) {
$hunks = $changeset->getHunks();
if (count($hunks) !== 1) {
$ignore_all = false;
} else {
$first_hunk = reset($hunks);
if ($first_hunk->getOldOffset() != 1 ||
$first_hunk->getNewOffset() != 1) {
$ignore_all = false;
}
}
}
if ($this->whitespaceMode == self::WHITESPACE_IGNORE_ALL &&
$can_use_ignore_all) {
if ($ignore_all) {
$old_file = $changeset->makeOldFile();
$new_file = $changeset->makeNewFile();
if ($old_file == $new_file) {
// If the old and new files are exactly identical, the synthetic
// diff below will give us nonsense and whitespace modes are
// irrelevant anyway. This occurs when you, e.g., copy a file onto
// itself in Subversion (see T271).
$ignore_all = false;
}
}
if ($ignore_all) {
// Huge mess. Generate a "-bw" (ignore all whitespace changes) diff,
// parse it out, and then play a shell game with the parsed format
@ -773,8 +797,8 @@ class DifferentialChangesetParser {
$old_tmp = new TempFile();
$new_tmp = new TempFile();
Filesystem::writeFile($old_tmp, $changeset->makeOldFile());
Filesystem::writeFile($new_tmp, $changeset->makeNewFile());
Filesystem::writeFile($old_tmp, $old_file);
Filesystem::writeFile($new_tmp, $new_file);
list($err, $diff) = exec_manual(
'diff -bw -U65535 %s %s ',
$old_tmp,
@ -849,10 +873,7 @@ EOSYNTHETIC;
$this->isTopLevel = (($range_start === null) && ($range_len === null));
$this->highlightEngine = new PhutilDefaultSyntaxHighlighterEngine();
$this->highlightEngine->setConfig(
'pygments.enabled',
PhabricatorEnv::getEnvConfig('pygments.enabled'));
$this->highlightEngine = PhabricatorSyntaxHighlighter::newEngine();
$this->tryCacheStuff();

View file

@ -14,7 +14,7 @@ phutil_require_module('phabricator', 'applications/differential/storage/changese
phutil_require_module('phabricator', 'applications/differential/storage/diff');
phutil_require_module('phabricator', 'applications/differential/view/inlinecomment');
phutil_require_module('phabricator', 'applications/files/uri');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phabricator', 'applications/markup/syntax');
phutil_require_module('phabricator', 'infrastructure/javelin/markup');
phutil_require_module('phabricator', 'storage/queryfx');
@ -24,7 +24,6 @@ phutil_require_module('phutil', 'filesystem/tempfile');
phutil_require_module('phutil', 'future');
phutil_require_module('phutil', 'future/exec');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'markup/syntax/engine/default');
phutil_require_module('phutil', 'utils');

View file

@ -31,6 +31,10 @@ class DifferentialReplyHandler extends PhabricatorMailReplyHandler {
return $this->getDefaultPrivateReplyHandlerEmailAddress($handle, 'D');
}
public function getPublicReplyHandlerEmailAddress() {
return $this->getDefaultPublicReplyHandlerEmailAddress('D');
}
public function getReplyHandlerDomain() {
return PhabricatorEnv::getEnvConfig(
'metamta.differential.reply-handler-domain');

View file

@ -179,13 +179,11 @@ class DiffusionBrowseFileController extends DiffusionController {
list($text_list, $rev_list, $blame_dict) = $file_query->getBlameData();
$highlightEngine = new PhutilDefaultSyntaxHighlighterEngine();
$highlightEngine->setConfig(
'pygments.enabled',
PhabricatorEnv::getEnvConfig('pygments.enabled'));
$text_list = explode("\n", $highlightEngine->highlightSource($path,
implode("\n", $text_list)));
$text_list = implode("\n", $text_list);
$text_list = PhabricatorSyntaxHighlighter::highlightWithFilename(
$path,
$text_list);
$text_list = explode("\n", $text_list);
$rows = $this->buildDisplayRows($text_list, $rev_list, $blame_dict,
$needs_blame, $drequest, $file_query, $selected);

View file

@ -8,13 +8,12 @@
phutil_require_module('phabricator', 'applications/diffusion/controller/base');
phutil_require_module('phabricator', 'applications/diffusion/query/filecontent/base');
phutil_require_module('phabricator', 'applications/markup/syntax');
phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phabricator', 'infrastructure/javelin/api');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'markup/syntax/engine/default');
phutil_require_module('phutil', 'utils');

View file

@ -0,0 +1,34 @@
<?php
/*
* Copyright 2011 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 PhabricatorFeedController extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = $this->buildStandardPageView();
$page->setApplicationName('Feed');
$page->setBaseURI('/feed/');
$page->setTitle(idx($data, 'title'));
$page->setGlyph("\xE2\x88\x9E");
$page->appendChild($view);
$response = new AphrontWebpageResponse();
return $response->setContent($page->render());
}
}

View file

@ -0,0 +1,15 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/webpage');
phutil_require_module('phabricator', 'applications/base/controller/base');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorFeedController.php');

View file

@ -0,0 +1,37 @@
<?php
/*
* Copyright 2011 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 PhabricatorFeedStreamController extends PhabricatorFeedController {
public function processRequest() {
$query = new PhabricatorFeedQuery();
$stories = $query->execute();
$views = array();
foreach ($stories as $story) {
$views[] = $story->renderView();
}
return $this->buildStandardPageResponse(
$views,
array(
'title' => 'Feed',
));
}
}

View file

@ -0,0 +1,13 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/feed/controller/base');
phutil_require_module('phabricator', 'applications/feed/query');
phutil_require_source('PhabricatorFeedStreamController.php');

View file

@ -0,0 +1,113 @@
<?php
/*
* Copyright 2011 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 PhabricatorFeedStoryPublisher {
private $relatedPHIDs;
private $storyType;
private $storyData;
private $storyTime;
private $storyAuthorPHID;
public function setRelatedPHIDs(array $phids) {
$this->relatedPHIDs = $phids;
return $this;
}
public function setStoryType($story_type) {
$this->storyType = $story_type;
return $this;
}
public function setStoryData(array $data) {
$this->storyData = $data;
return $this;
}
public function setStoryTime($time) {
$this->storyTime = $time;
return $this;
}
public function setStoryAuthorPHID($phid) {
$this->storyAuthorPHID = $phid;
return $this;
}
public function publish() {
if (!$this->relatedPHIDs) {
throw new Exception("There are no PHIDs related to this story!");
}
if (!$this->storyType) {
throw new Exception("Call setStoryType() before publishing!");
}
$chrono_key = $this->generateChronologicalKey();
$story = new PhabricatorFeedStoryData();
$story->setStoryType($this->storyType);
$story->setStoryData($this->storyData);
$story->setAuthorPHID($this->storyAuthorPHID);
$story->setChronologicalKey($chrono_key);
$story->save();
$ref = new PhabricatorFeedStoryReference();
$sql = array();
$conn = $ref->establishConnection('w');
foreach ($this->relatedPHIDs as $phid) {
$sql[] = qsprintf(
$conn,
'(%s, %s)',
$phid,
$chrono_key);
}
queryfx(
$conn,
'INSERT INTO %T (objectPHID, chronologicalKey) VALUES %Q',
$ref->getTableName(),
implode(', ', $sql));
return $story;
}
/**
* We generate a unique chronological key for each story type because we want
* to be able to page through the stream with a cursor (i.e., select stories
* after ID = X) so we can efficiently perform filtering after selecting data,
* and multiple stories with the same ID make this cumbersome without putting
* a bunch of logic in the client. We could use the primary key, but that
* would prevent publishing stories which happened in the past. Since it's
* potentially useful to do that (e.g., if you're importing another data
* source) build a unique key for each story which has chronological ordering.
*
* @return string A unique, time-ordered key which identifies the story.
*/
private function generateChronologicalKey() {
// Use the epoch timestamp for the upper 32 bits of the key. Default to
// the current time if the story doesn't have an explicit timestamp.
$time = nonempty($this->storyTime, time());
// Generate a random number for the lower 32 bits of the key.
$rand = head(unpack('L', Filesystem::readRandomBytes(4)));
return ($time << 32) + ($rand);
}
}

View file

@ -0,0 +1,18 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/feed/storage/story');
phutil_require_module('phabricator', 'applications/feed/storage/storyreference');
phutil_require_module('phabricator', 'storage/qsprintf');
phutil_require_module('phabricator', 'storage/queryfx');
phutil_require_module('phutil', 'filesystem');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorFeedStoryPublisher.php');

View file

@ -0,0 +1,95 @@
<?php
/*
* Copyright 2011 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 PhabricatorFeedQuery {
private $filterPHIDs;
private $limit = 100;
private $after;
public function setFilterPHIDs(array $phids) {
$this->filterPHIDs = $phids;
return $this;
}
public function setLimit($limit) {
$this->limit = $limit;
return $this;
}
public function setAfter($after) {
$this->after = $after;
return $this;
}
public function execute() {
$ref_table = new PhabricatorFeedStoryReference();
$story_table = new PhabricatorFeedStoryData();
$conn = $story_table->establishConnection('r');
$where = array();
if ($this->filterPHIDs) {
$where[] = qsprintf(
$conn,
'ref.objectPHID IN (%Ls)',
$this->filterPHIDs);
}
if ($where) {
$where = 'WHERE ('.implode(') AND (', $where).')';
} else {
$where = '';
}
$data = queryfx_all(
$conn,
'SELECT story.* FROM %T ref
JOIN %T story ON ref.chronologicalKey = story.chronologicalKey
%Q
GROUP BY story.chronologicalKey
ORDER BY story.chronologicalKey DESC
LIMIT %d',
$ref_table->getTableName(),
$story_table->getTableName(),
$where,
$this->limit);
$data = $story_table->loadAllFromArray($data);
$stories = array();
foreach ($data as $story_data) {
$class = $story_data->getStoryType();
try {
if (!class_exists($class) ||
!is_subclass_of($class, 'PhabricatorFeedStory')) {
$class = 'PhabricatorFeedStoryUnknown';
}
} catch (PhutilMissingSymbolException $ex) {
// If the class can't be loaded, libphutil will throw an exception.
// Render the story using the unknown story view.
$class = 'PhabricatorFeedStoryUnknown';
}
$stories[] = newv($class, array($story_data));
}
return $stories;
}
}

View file

@ -0,0 +1,17 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/feed/storage/story');
phutil_require_module('phabricator', 'applications/feed/storage/storyreference');
phutil_require_module('phabricator', 'storage/qsprintf');
phutil_require_module('phabricator', 'storage/queryfx');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorFeedQuery.php');

View file

@ -0,0 +1,25 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorFeedDAO extends PhabricatorLiskDAO {
public function getApplicationName() {
return 'feed';
}
}

View file

@ -0,0 +1,12 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/base/storage/lisk');
phutil_require_source('PhabricatorFeedDAO.php');

View file

@ -0,0 +1,42 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorFeedStoryData extends PhabricatorFeedDAO {
protected $phid;
protected $storyType;
protected $storyData;
protected $authorPHID;
protected $chronologicalKey;
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'storyData' => self::SERIALIZATION_JSON,
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorPHIDConstants::PHID_TYPE_STRY);
}
}

View file

@ -0,0 +1,14 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/feed/storage/base');
phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/storage/phid');
phutil_require_source('PhabricatorFeedStoryData.php');

View file

@ -0,0 +1,31 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorFeedStoryReference extends PhabricatorFeedDAO {
protected $objectPHID;
protected $chronologicalKey;
public function getConfiguration() {
return array(
self::CONFIG_IDS => self::IDS_MANUAL,
self::CONFIG_TIMESTAMPS => false,
) + parent::getConfiguration();
}
}

View file

@ -0,0 +1,12 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/feed/storage/base');
phutil_require_source('PhabricatorFeedStoryReference.php');

View file

@ -0,0 +1,29 @@
<?php
/*
* Copyright 2011 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 PhabricatorFeedStory {
private $data;
final public function __construct(PhabricatorFeedStoryData $data) {
$this->data = $data;
}
abstract public function renderView();
}

View file

@ -0,0 +1,10 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_source('PhabricatorFeedStory.php');

View file

@ -0,0 +1,25 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorFeedStoryUnknown extends PhabricatorFeedStory {
public function renderView() {
return new PhabricatorFeedStoryView();
}
}

View file

@ -0,0 +1,13 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/feed/story/base');
phutil_require_module('phabricator', 'applications/feed/view/story');
phutil_require_source('PhabricatorFeedStoryUnknown.php');

View file

@ -0,0 +1,21 @@
<?php
/*
* Copyright 2011 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 PhabricatorFeedView extends AphrontView {
}

View file

@ -0,0 +1,12 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'view/base');
phutil_require_source('PhabricatorFeedView.php');

View file

@ -0,0 +1,32 @@
<?php
/*
* Copyright 2011 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.
*/
class PhabricatorFeedStoryView extends PhabricatorFeedView {
public function render() {
return phutil_render_tag(
'div',
array(
'style' => 'border: 1px dashed black; '.
'padding: 1em; margin: 1em; '.
'background: #ffeedd;',
),
'This is a feed story!');
}
}

View file

@ -0,0 +1,14 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/feed/view/base');
phutil_require_module('phutil', 'markup');
phutil_require_source('PhabricatorFeedStoryView.php');

View file

@ -93,6 +93,12 @@ class HeraldRuleController extends HeraldController {
$conditions = array();
foreach ($data['conditions'] as $condition) {
if ($condition === null) {
// We manage this as a sparse array on the client, so may receive
// NULL if conditions have been removed.
continue;
}
$obj = new HeraldCondition();
$obj->setFieldName($condition[0]);
$obj->setFieldCondition($condition[1]);
@ -149,6 +155,11 @@ class HeraldRuleController extends HeraldController {
$actions = array();
foreach ($data['actions'] as $action) {
if ($action === null) {
// Sparse on the client; removals can give us NULLs.
continue;
}
$obj = new HeraldAction();
$obj->setAction($action[0]);

View file

@ -42,40 +42,45 @@ class HeraldTranscriptController extends HeraldController {
throw new Exception('Uknown transcript!');
}
$field_names = HeraldFieldConfig::getFieldMap();
$condition_names = HeraldConditionConfig::getConditionMap();
$action_names = HeraldActionConfig::getActionMap();
require_celerity_resource('herald-test-css');
$filter = $this->getFilterPHIDs();
$this->filterTranscript($xscript, $filter);
$phids = array_merge($filter, $this->getTranscriptPHIDs($xscript));
$phids = array_unique($phids);
$phids = array_filter($phids);
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles();
$this->handles = $handles;
$object_xscript = $xscript->getObjectTranscript();
$nav = $this->buildSideNav();
$apply_xscript_panel = $this->buildApplyTranscriptPanel(
$xscript);
$nav->appendChild($apply_xscript_panel);
$object_xscript = $xscript->getObjectTranscript();
if (!$object_xscript) {
$notice = id(new AphrontErrorView())
->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
->setTitle('Old Transcript')
->appendChild(
'<p>Details of this transcript have been garbage collected.</p>');
$nav->appendChild($notice);
} else {
$filter = $this->getFilterPHIDs();
$this->filterTranscript($xscript, $filter);
$phids = array_merge($filter, $this->getTranscriptPHIDs($xscript));
$phids = array_unique($phids);
$phids = array_filter($phids);
$action_xscript_panel = $this->buildActionTranscriptPanel(
$xscript);
$nav->appendChild($action_xscript_panel);
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles();
$this->handles = $handles;
$object_xscript_panel = $this->buildObjectTranscriptPanel(
$xscript);
$nav->appendChild($object_xscript_panel);
$apply_xscript_panel = $this->buildApplyTranscriptPanel(
$xscript);
$nav->appendChild($apply_xscript_panel);
$action_xscript_panel = $this->buildActionTranscriptPanel(
$xscript);
$nav->appendChild($action_xscript_panel);
$object_xscript_panel = $this->buildObjectTranscriptPanel(
$xscript);
$nav->appendChild($object_xscript_panel);
}
/*
TODO
$notice = null;
if ($xscript->getDryRun()) {
@ -84,30 +89,6 @@ class HeraldTranscriptController extends HeraldController {
This was a dry run to test Herald rules, no actions were executed.
</tools:notice>;
}
if (!$object_xscript) {
$notice =
<x:frag>
<tools:notice title="Old Transcript">
Details of this transcript have been discarded. Full transcripts
are retained for 30 days.
</tools:notice>
{$notice}
</x:frag>;
}
return
<herald:standard-page title="Transcript">
<div style="padding: 1em;">
<tools:side-nav items={$this->renderNavItems()}>
{$notice}
{$apply_xscript_markup}
{$rule_table}
{$object_xscript_table}
</tools:side-nav>
</div>
</herald:standard-page>;
*/
return $this->buildStandardPageResponse(
@ -264,7 +245,7 @@ class HeraldTranscriptController extends HeraldController {
foreach ($xscript->getApplyTranscripts() as $id => $apply_xscript) {
$rule_id = $apply_xscript->getRuleID();
if ($filter_owned) {
if (!$rule_xscripts[$rule_id]) {
if (empty($rule_xscripts[$rule_id])) {
// No associated rule so you can't own this effect.
continue;
}

View file

@ -14,6 +14,7 @@ phutil_require_module('phabricator', 'applications/herald/storage/transcript/bas
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'view/control/table');
phutil_require_module('phabricator', 'view/form/error');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phabricator', 'view/layout/sidenav');

Some files were not shown because too many files have changed in this diff Show more