Page MenuHomePhorge

No OneTemporary

diff --git a/src/applications/herald/controller/rule/__init__.php b/src/applications/herald/controller/rule/__init__.php
index 8ce0b727a7..a168848529 100644
--- a/src/applications/herald/controller/rule/__init__.php
+++ b/src/applications/herald/controller/rule/__init__.php
@@ -1,29 +1,30 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'applications/herald/config/action');
phutil_require_module('phabricator', 'applications/herald/config/condition');
phutil_require_module('phabricator', 'applications/herald/config/contenttype');
phutil_require_module('phabricator', 'applications/herald/config/field');
phutil_require_module('phabricator', 'applications/herald/config/valuetype');
phutil_require_module('phabricator', 'applications/herald/controller/base');
phutil_require_module('phabricator', 'applications/herald/storage/action');
phutil_require_module('phabricator', 'applications/herald/storage/condition');
phutil_require_module('phabricator', 'applications/herald/storage/rule');
phutil_require_module('phabricator', 'applications/phid/handle/data');
+phutil_require_module('phabricator', 'infrastructure/javelin/api');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('HeraldRuleController.php');
diff --git a/src/applications/search/execute/mysql/PhabricatorSearchMySQLExecutor.php b/src/applications/search/execute/mysql/PhabricatorSearchMySQLExecutor.php
index 41b2dc8a0b..e28a861507 100644
--- a/src/applications/search/execute/mysql/PhabricatorSearchMySQLExecutor.php
+++ b/src/applications/search/execute/mysql/PhabricatorSearchMySQLExecutor.php
@@ -1,181 +1,186 @@
<?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 PhabricatorSearchMySQLExecutor extends PhabricatorSearchExecutor {
public function executeSearch(PhabricatorSearchQuery $query) {
$where = array();
$join = array();
$order = 'ORDER BY documentCreated DESC';
$dao_doc = new PhabricatorSearchDocument();
$dao_field = new PhabricatorSearchDocumentField();
$t_doc = $dao_doc->getTableName();
$t_field = $dao_field->getTableName();
$conn_r = $dao_doc->establishConnection('r');
$q = $query->getQuery();
if (strlen($q)) {
$join[] = qsprintf(
$conn_r,
"{$t_field} field ON field.phid = document.phid");
$where[] = qsprintf(
$conn_r,
'MATCH(corpus) AGAINST (%s)',
$q);
-/*
- if ($query->getParameter('order') == AdjutantQuery::ORDER_RELEVANCE) {
+
+// if ($query->getParameter('order') == AdjutantQuery::ORDER_RELEVANCE) {
$order = qsprintf(
$conn_r,
- 'ORDER BY MATCH(corpus) AGAINST (%s) DESC',
+ 'ORDER BY MAX(MATCH(corpus) AGAINST (%s)) DESC',
$q);
- }
-*/
+// }
+
$field = $query->getParameter('field');
if ($field/* && $field != AdjutantQuery::FIELD_ALL*/) {
$where[] = qsprintf(
$conn_r,
'field.field = %s',
$field);
}
}
if ($query->getParameter('type')) {
if (strlen($q)) {
// TODO: verify that this column actually does something useful in query
// plans once we have nontrivial amounts of data.
$where[] = qsprintf(
$conn_r,
'field.phidType = %s',
$query->getParameter('type'));
}
$where[] = qsprintf(
$conn_r,
'document.documentType = %s',
$query->getParameter('type'));
}
$join[] = $this->joinRelationship(
$conn_r,
$query,
'author',
PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR);
$join[] = $this->joinRelationship(
$conn_r,
$query,
'open',
PhabricatorSearchRelationship::RELATIONSHIP_OPEN);
$join[] = $this->joinRelationship(
$conn_r,
$query,
'owner',
PhabricatorSearchRelationship::RELATIONSHIP_OWNER);
$join[] = $this->joinRelationship(
$conn_r,
$query,
'project',
PhabricatorSearchRelationship::RELATIONSHIP_PROJECT);
/*
$join[] = $this->joinRelationship(
$conn_r,
$query,
'reviewer',
AdjutantRelationship::RELATIONSHIP_REVIEWER);
$join[] = $this->joinRelationship(
$conn_r,
$query,
'subscriber',
AdjutantRelationship::RELATIONSHIP_SUBSCRIBER);
$join[] = $this->joinRelationship(
$conn_r,
$query,
'repository',
AdjutantRelationship::RELATIONSHIP_REPOSITORY);
*/
$join = array_filter($join);
foreach ($join as $key => $clause) {
$join[$key] = ' JOIN '.$clause;
}
$join = implode(' ', $join);
if ($where) {
$where = 'WHERE '.implode(' AND ', $where);
} else {
$where = '';
}
$hits = queryfx_all(
$conn_r,
- 'SELECT DISTINCT
+ 'SELECT
document.phid,
document.documentType,
document.documentTitle,
- document.documentCreated FROM %T document %Q %Q %Q
+ document.documentCreated
+ FROM %T document
+ %Q
+ %Q
+ GROUP BY document.phid
+ %Q
LIMIT 50',
$t_doc,
$join,
$where,
$order);
return $hits;
}
protected function joinRelationship($conn, $query, $field, $type) {
$phids = $query->getParameter($field, array());
if (!$phids) {
return null;
}
$is_existence = false;
switch ($type) {
case PhabricatorSearchRelationship::RELATIONSHIP_OPEN:
$is_existence = true;
break;
}
$sql = qsprintf(
$conn,
'%T AS %C ON %C.phid = document.phid AND %C.relation = %s',
id(new PhabricatorSearchDocumentRelationship())->getTableName(),
$field,
$field,
$field,
$type);
if (!$is_existence) {
$sql .= qsprintf(
$conn,
' AND %C.relatedPHID in (%Ls)',
$field,
$phids);
}
return $sql;
}
}
diff --git a/webroot/rsrc/js/application/herald/HeraldRuleEditor.js b/webroot/rsrc/js/application/herald/HeraldRuleEditor.js
index a6bce77dda..2937030507 100644
--- a/webroot/rsrc/js/application/herald/HeraldRuleEditor.js
+++ b/webroot/rsrc/js/application/herald/HeraldRuleEditor.js
@@ -1,363 +1,363 @@
/**
* @requires multirow-row-manager
* javelin-lib-dev
* javelin-typeahead-dev
* @provides herald-rule-editor
* @javelin
*/
JX.install('HeraldRuleEditor', {
construct : function(config) {
var root = JX.$(config.root);
this._root = root;
JX.DOM.listen(
root,
'click',
'create-condition',
JX.bind(this, this._onnewcondition));
JX.DOM.listen(
root,
'click',
'create-action',
JX.bind(this, this._onnewaction));
JX.DOM.listen(root, 'change', null, JX.bind(this, this._onchange));
JX.DOM.listen(root, 'submit', null, JX.bind(this, this._onsubmit));
var conditionsTable = JX.DOM.find(root, 'table', 'rule-conditions');
var actionsTable = JX.DOM.find(root, 'table', 'rule-actions');
this._conditionsRowManager = new JX.MultirowRowManager(conditionsTable);
this._conditionsRowManager.listen(
'row-removed',
JX.bind(this, function(row_id) {
delete this._config.conditions[row_id];
}));
this._actionsRowManager = new JX.MultirowRowManager(actionsTable);
this._actionsRowManager.listen(
'row-removed',
JX.bind(this, function(row_id) {
delete this._config.actions[row_id];
}));
this._conditionGetters = {};
this._conditionTypes = {};
this._actionGetters = {};
this._actionTypes = {};
this._config = config;
var conditions = this._config.conditions;
this._config.conditions = [];
var actions = this._config.actions;
this._config.actions = [];
this._renderConditions(conditions);
this._renderActions(actions);
},
members : {
_config : null,
_root : null,
_conditionGetters : null,
_conditionTypes : null,
_actionGetters : null,
_actionTypes : null,
_conditionsRowManager : null,
_actionsRowManager : null,
_onnewcondition : function(e) {
this._newCondition();
e.kill();
},
_onnewaction : function(e) {
this._newAction();
e.kill();
},
_onchange : function(e) {
var target = e.getTarget();
var row = e.getNode(JX.MultirowRowManager.getRowSigil());
if (!row) {
// Changing the "when all of / any of these..." dropdown.
return;
}
if (JX.Stratcom.hasSigil(target, 'field-select')) {
this._onfieldchange(row);
} else if (JX.Stratcom.hasSigil(target, 'condition-select')) {
this._onconditionchange(row);
} else if (JX.Stratcom.hasSigil(target, 'action-select')) {
this._onactionchange(row);
}
},
_onsubmit : function(e) {
var rule = JX.DOM.find(this._root, 'input', 'rule');
var k;
for (k in this._config.conditions) {
this._config.conditions[k][2] = this._getConditionValue(k);
}
var acts = this._config.actions;
for (k in this._config.actions) {
this._config.actions[k][1] = this._getActionTarget(k);
}
rule.value = JX.JSON.serialize({
conditions: this._config.conditions,
actions: this._config.actions
});
},
_getConditionValue : function(id) {
if (this._conditionGetters[id]) {
return this._conditionGetters[id]();
}
return this._config.conditions[id][2];
},
_getActionTarget : function(id) {
if (this._actionGetters[id]) {
return this._actionGetters[id]();
}
return this._config.actions[id][1];
},
_onactionchange : function(r) {
var target = JX.DOM.find(r, 'select', 'action-select');
var row_id = this._actionsRowManager.getRowID(r);
this._config.actions[row_id][0] = target.value;
var target_cell = JX.DOM.find(r, 'td', 'target-cell');
var target_input = this._renderTargetInputForRow(row_id);
JX.DOM.setContent(target_cell, target_input);
},
_onfieldchange : function(r) {
var target = JX.DOM.find(r, 'select', 'field-select');
var row_id = this._actionsRowManager.getRowID(r);
this._config.conditions[row_id][0] = target.value;
var condition_cell = JX.DOM.find(r, 'td', 'condition-cell');
var condition_select = this._renderSelect(
this._selectKeys(
this._config.info.conditions,
this._config.info.conditionMap[target.value]),
this._config.conditions[row_id][1],
'condition-select');
JX.DOM.setContent(condition_cell, condition_select);
this._onconditionchange(r);
},
_onconditionchange : function(r) {
var target = JX.DOM.find(r, 'select', 'condition-select');
var row_id = this._conditionsRowManager.getRowID(r);
this._config.conditions[row_id][1] = target.value;
var value_cell = JX.DOM.find(r, 'td', 'value-cell');
var value_input = this._renderValueInputForRow(row_id);
JX.DOM.setContent(value_cell, value_input);
},
_renderTargetInputForRow : function(row_id) {
var action = this._config.actions[row_id];
var type = this._config.info.targets[action[0]];
var input = this._buildInput(type);
var node = input[0];
var get_fn = input[1];
var set_fn = input[2];
if (node) {
JX.Stratcom.addSigil(node, 'action-target');
}
var old_type = this._actionTypes[row_id];
if (old_type == type || !old_type) {
set_fn(this._getActionTarget(row_id));
}
this._actionTypes[row_id] = type;
this._actionGetters[row_id] = get_fn;
return node;
},
_buildInput : function(type) {
var input;
var get_fn;
var set_fn;
switch (type) {
case 'rule':
input = this._renderSelect(this._config.template.rules);
get_fn = function() { return input.value; };
set_fn = function(v) { input.value = v; };
break;
case 'email':
case 'employee':
case 'repository':
case 'tag':
case 'package':
var tokenizer = this._newTokenizer(type);
input = tokenizer[0];
get_fn = tokenizer[1];
set_fn = tokenizer[2];
break;
case 'none':
input = '';
get_fn = JX.bag;
set_fn = JX.bag;
break;
default:
input = JX.$N('input');
get_fn = function() { return input.value; };
set_fn = function(v) { input.value = v; };
break;
}
return [input, get_fn, set_fn];
},
_renderValueInputForRow : function(row_id) {
var cond = this._config.conditions[row_id];
var type = this._config.info.values[cond[0]][cond[1]];
var input = this._buildInput(type);
var node = input[0];
var get_fn = input[1];
var set_fn = input[2];
if (node) {
JX.Stratcom.addSigil(node, 'condition-value');
}
var old_type = this._conditionTypes[row_id];
if (old_type == type || !old_type) {
set_fn(this._getConditionValue(row_id));
}
this._conditionTypes[row_id] = type;
this._conditionGetters[row_id] = get_fn;
return node;
},
_newTokenizer : function(type) {
var template = JX.$N(
'div',
new JX.HTML(this._config.template.markup));
template = template.firstChild;
template.id = '';
var datasource = new JX.TypeaheadPreloadedSource(
this._config.template.source[type]);
var typeahead = new JX.Typeahead(template);
typeahead.setDatasource(datasource);
var tokenizer = new JX.Tokenizer(template);
tokenizer.setTypeahead(typeahead);
tokenizer.start();
return [
template,
function() {
return tokenizer.getTokens();
},
function(map) {
for (var k in map) {
tokenizer.addToken(k, map[k]);
}
}];
},
_selectKeys : function(map, keys) {
var r = {};
for (var ii = 0; ii < keys.length; ii++) {
r[keys[ii]] = map[keys[ii]];
}
return r;
},
_renderConditions : function(conditions) {
for (var k in conditions) {
this._newCondition(conditions[k]);
}
},
_newCondition : function(data) {
var row = this._conditionsRowManager.addRow([]);
var row_id = this._conditionsRowManager.getRowID(row);
this._config.conditions[row_id] = data || [null, null, ''];
var r = this._conditionsRowManager.updateRow(
row_id,
this._renderCondition(row_id));
this._onfieldchange(r);
},
_renderCondition : function(row_id) {
var field_select = this._renderSelect(
this._config.info.fields,
this._config.conditions[row_id][0],
'field-select');
var field_cell = JX.$N('td', {sigil: 'field-cell'}, field_select);
var condition_cell = JX.$N('td', {sigil: 'condition-cell'});
var value_cell = JX.$N('td', {className : 'value', sigil: 'value-cell'});
return [field_cell, condition_cell, value_cell];
},
_renderActions : function(actions) {
for (var k in actions) {
this._newAction(actions[k]);
delete actions[k];
}
},
_newAction : function(data) {
data = data || [];
var temprow = this._actionsRowManager.addRow([]);
var row_id = this._actionsRowManager.getRowID(temprow);
this._config.actions[row_id] = data;
var r = this._actionsRowManager.updateRow(row_id,
this._renderAction(data));
this._onactionchange(r);
},
_renderAction : function(action) {
var action_select = this._renderSelect(
this._config.info.actions,
action[0],
'action-select');
var action_cell = JX.$N('td', {sigil: 'action-cell'}, action_select);
var target_cell = JX.$N(
'td',
{className : 'target', sigil : 'target-cell'});
return [action_cell, target_cell];
},
_renderSelect : function(map, selected, sigil) {
var select = JX.$N(
'select',
{
style : {width: '250px', margin: '0 .5em 0 0'},
sigil : sigil
});
for (var k in map) {
select.options[select.options.length] = new Option(map[k], k);
if (k == selected) {
select.value = k;
}
}
select.value = select.value || JX.keys(map)[0];
return select;
}
}
-});
\ No newline at end of file
+});

File Metadata

Mime Type
text/x-diff
Expires
Sun, Jan 19, 18:17 (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1127355
Default Alt Text
(17 KB)

Event Timeline