Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2313083
ManiphestBatchEditController.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
ManiphestBatchEditController.php
View Options
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group maniphest
*/
final
class
ManiphestBatchEditController
extends
ManiphestController
{
public
function
processRequest
()
{
$request
=
$this
->
getRequest
();
$user
=
$request
->
getUser
();
$task_ids
=
$request
->
getArr
(
'batch'
);
$tasks
=
id
(
new
ManiphestTask
())->
loadAllWhere
(
'id IN (%Ld)'
,
$task_ids
);
$actions
=
$request
->
getStr
(
'actions'
);
if
(
$actions
)
{
$actions
=
json_decode
(
$actions
,
true
);
}
if
(
$request
->
isFormPost
()
&&
is_array
(
$actions
))
{
foreach
(
$tasks
as
$task
)
{
$xactions
=
$this
->
buildTransactions
(
$actions
,
$task
);
if
(
$xactions
)
{
$editor
=
new
ManiphestTransactionEditor
();
$editor
->
setActor
(
$user
);
$editor
->
applyTransactions
(
$task
,
$xactions
);
}
}
$task_ids
=
implode
(
','
,
mpull
(
$tasks
,
'getID'
));
return
id
(
new
AphrontRedirectResponse
())
->
setURI
(
'/maniphest/view/custom/?s=oc&tasks='
.
$task_ids
);
}
$panel
=
new
AphrontPanelView
();
$panel
->
setHeader
(
'Maniphest Batch Editor'
);
$handle_phids
=
mpull
(
$tasks
,
'getOwnerPHID'
);
$handles
=
$this
->
loadViewerHandles
(
$handle_phids
);
$list
=
new
ManiphestTaskListView
();
$list
->
setTasks
(
$tasks
);
$list
->
setUser
(
$user
);
$list
->
setHandles
(
$handles
);
$template
=
new
AphrontTokenizerTemplateView
();
$template
=
$template
->
render
();
require_celerity_resource
(
'maniphest-batch-editor'
);
Javelin
::
initBehavior
(
'maniphest-batch-editor'
,
array
(
'root'
=>
'maniphest-batch-edit-form'
,
'tokenizerTemplate'
=>
$template
,
'sources'
=>
array
(
'project'
=>
array
(
'src'
=>
'/typeahead/common/projects/'
,
'placeholder'
=>
'Type a project name...'
,
),
'owner'
=>
array
(
'src'
=>
'/typeahead/common/searchowner/'
,
'placeholder'
=>
'Type a user name...'
,
'limit'
=>
1
,
),
),
'input'
=>
'batch-form-actions'
,
'priorityMap'
=>
ManiphestTaskPriority
::
getTaskPriorityMap
(),
'statusMap'
=>
ManiphestTaskStatus
::
getTaskStatusMap
(),
));
$form
=
new
AphrontFormView
();
$form
->
setUser
(
$user
);
$form
->
setID
(
'maniphest-batch-edit-form'
);
foreach
(
$tasks
as
$task
)
{
$form
->
appendChild
(
phutil_render_tag
(
'input'
,
array
(
'type'
=>
'hidden'
,
'name'
=>
'batch[]'
,
'value'
=>
$task
->
getID
(),
),
null
));
}
$form
->
appendChild
(
phutil_render_tag
(
'input'
,
array
(
'type'
=>
'hidden'
,
'name'
=>
'actions'
,
'id'
=>
'batch-form-actions'
,
),
null
));
$form
->
appendChild
(
'<p>These tasks will be edited:</p>'
);
$form
->
appendChild
(
$list
);
$form
->
appendChild
(
id
(
new
AphrontFormInsetView
())
->
setTitle
(
'Actions'
)
->
setRightButton
(
javelin_render_tag
(
'a'
,
array
(
'href'
=>
'#'
,
'class'
=>
'button green'
,
'sigil'
=>
'add-action'
,
'mustcapture'
=>
true
,
),
'Add Another Action'
))
->
setContent
(
javelin_render_tag
(
'table'
,
array
(
'sigil'
=>
'maniphest-batch-actions'
,
'class'
=>
'maniphest-batch-actions-table'
,
),
''
)))
->
appendChild
(
id
(
new
AphrontFormSubmitControl
())
->
setValue
(
'Update Tasks'
)
->
addCancelButton
(
'/maniphest/'
,
'Done'
));
$panel
->
appendChild
(
$form
);
return
$this
->
buildStandardPageResponse
(
$panel
,
array
(
'title'
=>
'Batch Editor'
,
));
}
private
function
buildTransactions
(
$actions
,
ManiphestTask
$task
)
{
$value_map
=
array
();
$type_map
=
array
(
'add_comment'
=>
ManiphestTransactionType
::
TYPE_NONE
,
'assign'
=>
ManiphestTransactionType
::
TYPE_OWNER
,
'status'
=>
ManiphestTransactionType
::
TYPE_STATUS
,
'priority'
=>
ManiphestTransactionType
::
TYPE_PRIORITY
,
'add_project'
=>
ManiphestTransactionType
::
TYPE_PROJECTS
,
'remove_project'
=>
ManiphestTransactionType
::
TYPE_PROJECTS
,
);
$edge_edit_types
=
array
(
'add_project'
=>
true
,
'remove_project'
=>
true
,
);
$xactions
=
array
();
foreach
(
$actions
as
$action
)
{
if
(
empty
(
$type_map
[
$action
[
'action'
]]))
{
throw
new
Exception
(
"Unknown batch edit action '{$action}'!"
);
}
$type
=
$type_map
[
$action
[
'action'
]];
// Figure out the current value, possibly after modifications by other
// batch actions of the same type. For example, if the user chooses to
// "Add Comment" twice, we should add both comments. More notably, if the
// user chooses "Remove Project..." and also "Add Project...", we should
// avoid restoring the removed project in the second transaction.
if
(
array_key_exists
(
$type
,
$value_map
))
{
$current
=
$value_map
[
$type
];
}
else
{
switch
(
$type
)
{
case
ManiphestTransactionType
::
TYPE_NONE
:
$current
=
null
;
break
;
case
ManiphestTransactionType
::
TYPE_OWNER
:
$current
=
$task
->
getOwnerPHID
();
break
;
case
ManiphestTransactionType
::
TYPE_STATUS
:
$current
=
$task
->
getStatus
();
break
;
case
ManiphestTransactionType
::
TYPE_PRIORITY
:
$current
=
$task
->
getPriority
();
break
;
case
ManiphestTransactionType
::
TYPE_PROJECTS
:
$current
=
$task
->
getProjectPHIDs
();
break
;
}
}
// Check if the value is meaningful / provided, and normalize it if
// necessary. This discards, e.g., empty comments and empty owner
// changes.
$value
=
$action
[
'value'
];
switch
(
$type
)
{
case
ManiphestTransactionType
::
TYPE_NONE
:
if
(!
strlen
(
$value
))
{
continue
2
;
}
break
;
case
ManiphestTransactionType
::
TYPE_OWNER
:
if
(
empty
(
$value
))
{
continue
2
;
}
$value
=
head
(
$value
);
if
(
$value
===
ManiphestTaskOwner
::
OWNER_UP_FOR_GRABS
)
{
$value
=
null
;
}
break
;
case
ManiphestTransactionType
::
TYPE_PROJECTS
:
if
(
empty
(
$value
))
{
continue
2
;
}
break
;
}
// If the edit doesn't change anything, go to the next action. This
// check is only valid for changes like "owner", "status", etc, not
// for edge edits, because we should still apply an edit like
// "Remove Projects: A, B" to a task with projects "A, B".
if
(
empty
(
$edge_edit_types
[
$action
[
'action'
]]))
{
if
(
$value
==
$current
)
{
continue
;
}
}
// Apply the value change; for most edits this is just replacement, but
// some need to merge the current and edited values (add/remove project).
switch
(
$type
)
{
case
ManiphestTransactionType
::
TYPE_NONE
:
if
(
strlen
(
$current
))
{
$value
=
$current
.
"
\n\n
"
.
$value
;
}
break
;
case
ManiphestTransactionType
::
TYPE_PROJECTS
:
$is_remove
=
(
$action
[
'action'
]
==
'remove_project'
);
$current
=
array_fill_keys
(
$current
,
true
);
$value
=
array_fill_keys
(
$value
,
true
);
$new
=
$current
;
$did_something
=
false
;
if
(
$is_remove
)
{
foreach
(
$value
as
$phid
=>
$ignored
)
{
if
(
isset
(
$new
[
$phid
]))
{
unset
(
$new
[
$phid
]);
$did_something
=
true
;
}
}
}
else
{
foreach
(
$value
as
$phid
=>
$ignored
)
{
if
(
empty
(
$new
[
$phid
]))
{
$new
[
$phid
]
=
true
;
$did_something
=
true
;
}
}
}
if
(!
$did_something
)
{
continue
2
;
}
$value
=
array_keys
(
$new
);
break
;
}
$value_map
[
$type
]
=
$value
;
}
$template
=
new
ManiphestTransaction
();
$template
->
setAuthorPHID
(
$this
->
getRequest
()->
getUser
()->
getPHID
());
// TODO: Set content source to "batch edit".
foreach
(
$value_map
as
$type
=>
$value
)
{
$xaction
=
clone
$template
;
$xaction
->
setTransactionType
(
$type
);
switch
(
$type
)
{
case
ManiphestTransactionType
::
TYPE_NONE
:
$xaction
->
setComments
(
$value
);
break
;
default
:
$xaction
->
setNewValue
(
$value
);
break
;
}
$xactions
[]
=
$xaction
;
}
return
$xactions
;
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Tue, Sep 16, 3:50 AM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
442348
Default Alt Text
ManiphestBatchEditController.php (9 KB)
Attached To
Mode
rP Phorge
Attached
Detach File
Event Timeline
Log In to Comment