private function attemptProjectEdit(PhabricatorProject $proj, PhabricatorUser $user, $skip_refresh = false)
 {
     $proj = $this->refreshProject($proj, $user, true);
     $new_name = $proj->getName() . ' ' . mt_rand();
     $xaction = new PhabricatorProjectTransaction();
     $xaction->setTransactionType(PhabricatorProjectTransactionType::TYPE_NAME);
     $xaction->setNewValue($new_name);
     $editor = new PhabricatorProjectEditor($proj);
     $editor->setUser($user);
     $editor->applyTransactions(array($xaction));
     return true;
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $project = id(new PhabricatorProjectQuery())->setViewer($user)->withIDs(array($this->id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
     if (!$project) {
         return new Aphront404Response();
     }
     $profile = $project->loadProfile();
     if (empty($profile)) {
         $profile = new PhabricatorProjectProfile();
     }
     $member_phids = $project->loadMemberPHIDs();
     $errors = array();
     if ($request->isFormPost()) {
         $changed_something = false;
         $member_map = array_fill_keys($member_phids, true);
         $remove = $request->getStr('remove');
         if ($remove) {
             if (isset($member_map[$remove])) {
                 unset($member_map[$remove]);
                 $changed_something = true;
             }
         } else {
             $new_members = $request->getArr('phids');
             foreach ($new_members as $member) {
                 if (empty($member_map[$member])) {
                     $member_map[$member] = true;
                     $changed_something = true;
                 }
             }
         }
         $xactions = array();
         if ($changed_something) {
             $xaction = new PhabricatorProjectTransaction();
             $xaction->setTransactionType(PhabricatorProjectTransactionType::TYPE_MEMBERS);
             $xaction->setNewValue(array_keys($member_map));
             $xactions[] = $xaction;
         }
         if ($xactions) {
             $editor = new PhabricatorProjectEditor($project);
             $editor->setUser($user);
             $editor->applyTransactions($xactions);
         }
         return id(new AphrontRedirectResponse())->setURI($request->getRequestURI());
     }
     $member_phids = array_reverse($member_phids);
     $handles = id(new PhabricatorObjectHandleData($member_phids))->loadHandles();
     $state = array();
     foreach ($handles as $handle) {
         $state[] = array('phid' => $handle->getPHID(), 'name' => $handle->getFullName());
     }
     $header_name = 'Edit Members';
     $title = 'Edit Members';
     $list = $this->renderMemberList($handles);
     $form = new AphrontFormView();
     $form->setUser($user)->appendChild(id(new AphrontFormTokenizerControl())->setName('phids')->setLabel('Add Members')->setDatasource('/typeahead/common/users/'))->appendChild(id(new AphrontFormSubmitControl())->addCancelButton('/project/view/' . $project->getID() . '/')->setValue('Add Members'));
     $faux_form = id(new AphrontFormLayoutView())->setBackgroundShading(true)->setPadded(true)->appendChild(id(new AphrontFormInsetView())->setTitle('Current Members (' . count($handles) . ')')->appendChild($list));
     $panel = new AphrontPanelView();
     $panel->setHeader($header_name);
     $panel->setWidth(AphrontPanelView::WIDTH_FORM);
     $panel->appendChild($form);
     $panel->appendChild('<br />');
     $panel->appendChild($faux_form);
     $nav = $this->buildLocalNavigation($project);
     $nav->selectFilter('members');
     $nav->appendChild($panel);
     return $this->buildStandardPageResponse($nav, array('title' => $title));
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $project = new PhabricatorProject();
     $project->setAuthorPHID($user->getPHID());
     $profile = new PhabricatorProjectProfile();
     $e_name = true;
     $errors = array();
     if ($request->isFormPost()) {
         try {
             $xactions = array();
             $xaction = new PhabricatorProjectTransaction();
             $xaction->setTransactionType(PhabricatorProjectTransactionType::TYPE_NAME);
             $xaction->setNewValue($request->getStr('name'));
             $xactions[] = $xaction;
             $editor = new PhabricatorProjectEditor($project);
             $editor->setUser($user);
             $editor->applyTransactions($xactions);
         } catch (PhabricatorProjectNameCollisionException $ex) {
             $e_name = 'Not Unique';
             $errors[] = $ex->getMessage();
         }
         $profile->setBlurb($request->getStr('blurb'));
         if (!$errors) {
             $project->save();
             $profile->setProjectPHID($project->getPHID());
             $profile->save();
             id(new PhabricatorProjectAffiliation())->setUserPHID($user->getPHID())->setProjectPHID($project->getPHID())->setRole('Owner')->setIsOwner(true)->save();
             if ($request->isAjax()) {
                 return id(new AphrontAjaxResponse())->setContent(array('phid' => $project->getPHID(), 'name' => $project->getName()));
             } else {
                 return id(new AphrontRedirectResponse())->setURI('/project/view/' . $project->getID() . '/');
             }
         }
     }
     $error_view = null;
     if ($errors) {
         $error_view = new AphrontErrorView();
         $error_view->setTitle('Form Errors');
         $error_view->setErrors($errors);
     }
     if ($request->isAjax()) {
         $form = new AphrontFormLayoutView();
     } else {
         $form = new AphrontFormView();
         $form->setUser($user);
     }
     $form->appendChild(id(new AphrontFormTextControl())->setLabel('Name')->setName('name')->setValue($project->getName())->setError($e_name))->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Blurb')->setName('blurb')->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT)->setValue($profile->getBlurb()));
     if ($request->isAjax()) {
         if ($error_view) {
             $error_view->setWidth(AphrontErrorView::WIDTH_DIALOG);
         }
         $dialog = id(new AphrontDialogView())->setUser($user)->setWidth(AphrontDialogView::WIDTH_FORM)->setTitle('Create a New Project')->appendChild($error_view)->appendChild($form)->addSubmitButton('Create Project')->addCancelButton('/project/');
         return id(new AphrontDialogResponse())->setDialog($dialog);
     } else {
         $form->appendChild(id(new AphrontFormSubmitControl())->setValue('Create')->addCancelButton('/project/'));
         $panel = new AphrontPanelView();
         $panel->setWidth(AphrontPanelView::WIDTH_FORM)->setHeader('Create a New Project')->appendChild($form);
         return $this->buildStandardPageResponse(array($error_view, $panel), array('title' => 'Create new Project'));
     }
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $project = id(new PhabricatorProjectQuery())->setViewer($user)->withIDs(array($this->id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
     if (!$project) {
         return new Aphront404Response();
     }
     $profile = $project->loadProfile();
     if (empty($profile)) {
         $profile = new PhabricatorProjectProfile();
     }
     $img_src = $profile->loadProfileImageURI();
     $options = PhabricatorProjectStatus::getStatusMap();
     $supported_formats = PhabricatorFile::getTransformableImageFormats();
     $e_name = true;
     $e_image = null;
     $errors = array();
     if ($request->isFormPost()) {
         try {
             $xactions = array();
             $xaction = new PhabricatorProjectTransaction();
             $xaction->setTransactionType(PhabricatorProjectTransactionType::TYPE_NAME);
             $xaction->setNewValue($request->getStr('name'));
             $xactions[] = $xaction;
             $xaction = new PhabricatorProjectTransaction();
             $xaction->setTransactionType(PhabricatorProjectTransactionType::TYPE_STATUS);
             $xaction->setNewValue($request->getStr('status'));
             $xactions[] = $xaction;
             $xaction = new PhabricatorProjectTransaction();
             $xaction->setTransactionType(PhabricatorProjectTransactionType::TYPE_CAN_VIEW);
             $xaction->setNewValue($request->getStr('can_view'));
             $xactions[] = $xaction;
             $xaction = new PhabricatorProjectTransaction();
             $xaction->setTransactionType(PhabricatorProjectTransactionType::TYPE_CAN_EDIT);
             $xaction->setNewValue($request->getStr('can_edit'));
             $xactions[] = $xaction;
             $xaction = new PhabricatorProjectTransaction();
             $xaction->setTransactionType(PhabricatorProjectTransactionType::TYPE_CAN_JOIN);
             $xaction->setNewValue($request->getStr('can_join'));
             $xactions[] = $xaction;
             $editor = new PhabricatorProjectEditor($project);
             $editor->setUser($user);
             $editor->applyTransactions($xactions);
         } catch (PhabricatorProjectNameCollisionException $ex) {
             $e_name = 'Not Unique';
             $errors[] = $ex->getMessage();
         }
         $profile->setBlurb($request->getStr('blurb'));
         if (!strlen($project->getName())) {
             $e_name = 'Required';
             $errors[] = 'Project name is required.';
         } else {
             $e_name = null;
         }
         $default_image = $request->getExists('default_image');
         if ($default_image) {
             $profile->setProfileImagePHID(null);
         } else {
             if (!empty($_FILES['image'])) {
                 $err = idx($_FILES['image'], 'error');
                 if ($err != UPLOAD_ERR_NO_FILE) {
                     $file = PhabricatorFile::newFromPHPUpload($_FILES['image'], array('authorPHID' => $user->getPHID()));
                     $okay = $file->isTransformableImage();
                     if ($okay) {
                         $xformer = new PhabricatorImageTransformer();
                         $xformed = $xformer->executeThumbTransform($file, $x = 50, $y = 50);
                         $profile->setProfileImagePHID($xformed->getPHID());
                     } else {
                         $e_image = 'Not Supported';
                         $errors[] = 'This server only supports these image formats: ' . implode(', ', $supported_formats) . '.';
                     }
                 }
             }
         }
         if (!$errors) {
             $project->save();
             $profile->setProjectPHID($project->getPHID());
             $profile->save();
             return id(new AphrontRedirectResponse())->setURI('/project/view/' . $project->getID() . '/');
         }
     }
     $error_view = null;
     if ($errors) {
         $error_view = new AphrontErrorView();
         $error_view->setTitle('Form Errors');
         $error_view->setErrors($errors);
     }
     $header_name = 'Edit Project';
     $title = 'Edit Project';
     $action = '/project/edit/' . $project->getID() . '/';
     $policies = id(new PhabricatorPolicyQuery())->setViewer($user)->setObject($project)->execute();
     $form = new AphrontFormView();
     $form->setID('project-edit-form')->setUser($user)->setAction($action)->setEncType('multipart/form-data')->appendChild(id(new AphrontFormTextControl())->setLabel('Name')->setName('name')->setValue($project->getName())->setError($e_name))->appendChild(id(new AphrontFormSelectControl())->setLabel('Project Status')->setName('status')->setOptions($options)->setValue($project->getStatus()))->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Blurb')->setName('blurb')->setValue($profile->getBlurb()))->appendChild('<p class="aphront-form-instructions">NOTE: Policy settings are not ' . 'yet fully implemented. Some interfaces still ignore these settings, ' . 'particularly "Visible To".</p>')->appendChild(id(new AphrontFormPolicyControl())->setUser($user)->setName('can_view')->setCaption('Members can always view a project.')->setPolicyObject($project)->setPolicies($policies)->setCapability(PhabricatorPolicyCapability::CAN_VIEW))->appendChild(id(new AphrontFormPolicyControl())->setUser($user)->setName('can_edit')->setPolicyObject($project)->setPolicies($policies)->setCapability(PhabricatorPolicyCapability::CAN_EDIT))->appendChild(id(new AphrontFormPolicyControl())->setUser($user)->setName('can_join')->setCaption('Users who can edit a project can always join a project.')->setPolicyObject($project)->setPolicies($policies)->setCapability(PhabricatorPolicyCapability::CAN_JOIN))->appendChild(id(new AphrontFormMarkupControl())->setLabel('Profile Image')->setValue(phutil_render_tag('img', array('src' => $img_src))))->appendChild(id(new AphrontFormImageControl())->setLabel('Change Image')->setName('image')->setError($e_image)->setCaption('Supported formats: ' . implode(', ', $supported_formats)))->appendChild(id(new AphrontFormSubmitControl())->addCancelButton('/project/view/' . $project->getID() . '/')->setValue('Save'));
     $panel = new AphrontPanelView();
     $panel->setHeader($header_name);
     $panel->setWidth(AphrontPanelView::WIDTH_FORM);
     $panel->appendChild($form);
     $nav = $this->buildLocalNavigation($project);
     $nav->selectFilter('edit');
     $nav->appendChild(array($error_view, $panel));
     return $this->buildStandardPageResponse($nav, array('title' => $title));
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $project = id(new PhabricatorProject())->load($this->id);
     if (!$project) {
         return new Aphront404Response();
     }
     $process_action = false;
     switch ($this->action) {
         case 'join':
             $process_action = $request->isFormPost();
             break;
         case 'leave':
             $process_action = $request->isDialogFormPost();
             break;
         default:
             return new Aphront404Response();
     }
     $project_uri = '/project/view/' . $project->getID() . '/';
     if ($process_action) {
         $xactions = array();
         switch ($this->action) {
             case 'join':
                 $affils = $project->loadAffiliations();
                 $affils = mpull($affils, null, 'getUserPHID');
                 if (empty($affils[$user->getPHID()])) {
                     $affils[$user->getPHID()] = true;
                     $xaction = new PhabricatorProjectTransaction();
                     $xaction->setTransactionType(PhabricatorProjectTransactionType::TYPE_MEMBERS);
                     $xaction->setNewValue(array_keys($affils));
                     $xactions[] = $xaction;
                 }
                 break;
             case 'leave':
                 $affils = $project->loadAffiliations();
                 $affils = mpull($affils, null, 'getUserPHID');
                 if (isset($affils[$user->getPHID()])) {
                     unset($affils[$user->getPHID()]);
                     $xaction = new PhabricatorProjectTransaction();
                     $xaction->setTransactionType(PhabricatorProjectTransactionType::TYPE_MEMBERS);
                     $xaction->setNewValue(array_keys($affils));
                     $xactions[] = $xaction;
                 }
                 break;
         }
         if ($xactions) {
             $editor = new PhabricatorProjectEditor($project);
             $editor->setUser($user);
             $editor->applyTransactions($xactions);
         }
         return id(new AphrontRedirectResponse())->setURI($project_uri);
     }
     $dialog = null;
     switch ($this->action) {
         case 'leave':
             $dialog = new AphrontDialogView();
             $dialog->setUser($user);
             $dialog->setTitle('Really leave project?');
             $dialog->appendChild('<p>Your tremendous contributions to this project will be sorely ' . 'missed. Are you sure you want to leave?</p>');
             $dialog->addCancelButton($project_uri);
             $dialog->addSubmitButton('Leave Project');
             break;
         default:
             return new Aphront404Response();
     }
     return id(new AphrontDialogResponse())->setDialog($dialog);
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $project = id(new PhabricatorProject())->load($this->id);
     if (!$project) {
         return new Aphront404Response();
     }
     $profile = $project->loadProfile();
     if (empty($profile)) {
         $profile = new PhabricatorProjectProfile();
     }
     $img_src = $profile->loadProfileImageURI();
     if ($project->getSubprojectPHIDs()) {
         $phids = $project->getSubprojectPHIDs();
         $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
         $subprojects = mpull($handles, 'getFullName', 'getPHID');
     } else {
         $subprojects = array();
     }
     $options = PhabricatorProjectStatus::getStatusMap();
     $affiliations = $project->loadAffiliations();
     $affiliations = mpull($affiliations, null, 'getUserPHID');
     $supported_formats = PhabricatorFile::getTransformableImageFormats();
     $e_name = true;
     $e_image = null;
     $errors = array();
     $state = null;
     if ($request->isFormPost()) {
         try {
             $xactions = array();
             $xaction = new PhabricatorProjectTransaction();
             $xaction->setTransactionType(PhabricatorProjectTransactionType::TYPE_NAME);
             $xaction->setNewValue($request->getStr('name'));
             $xactions[] = $xaction;
             $xaction = new PhabricatorProjectTransaction();
             $xaction->setTransactionType(PhabricatorProjectTransactionType::TYPE_STATUS);
             $xaction->setNewValue($request->getStr('status'));
             $xactions[] = $xaction;
             $editor = new PhabricatorProjectEditor($project);
             $editor->setUser($user);
             $editor->applyTransactions($xactions);
         } catch (PhabricatorProjectNameCollisionException $ex) {
             $e_name = 'Not Unique';
             $errors[] = $ex->getMessage();
         }
         $project->setSubprojectPHIDs($request->getArr('set_subprojects'));
         $profile->setBlurb($request->getStr('blurb'));
         if (!strlen($project->getName())) {
             $e_name = 'Required';
             $errors[] = 'Project name is required.';
         } else {
             $e_name = null;
         }
         $default_image = $request->getExists('default_image');
         if ($default_image) {
             $profile->setProfileImagePHID(null);
         } else {
             if (!empty($_FILES['image'])) {
                 $err = idx($_FILES['image'], 'error');
                 if ($err != UPLOAD_ERR_NO_FILE) {
                     $file = PhabricatorFile::newFromPHPUpload($_FILES['image'], array('authorPHID' => $user->getPHID()));
                     $okay = $file->isTransformableImage();
                     if ($okay) {
                         $xformer = new PhabricatorImageTransformer();
                         $xformed = $xformer->executeThumbTransform($file, $x = 50, $y = 50);
                         $profile->setProfileImagePHID($xformed->getPHID());
                     } else {
                         $e_image = 'Not Supported';
                         $errors[] = 'This server only supports these image formats: ' . implode(', ', $supported_formats) . '.';
                     }
                 }
             }
         }
         $resources = $request->getStr('resources');
         $resources = json_decode($resources, true);
         if (!is_array($resources)) {
             throw new Exception("Project resource information was not correctly encoded in the " . "request.");
         }
         $state = array();
         foreach ($resources as $resource) {
             $user_phid = $resource['phid'];
             if (!$user_phid) {
                 continue;
             }
             if (isset($state[$user_phid])) {
                 // TODO: We should deal with this better -- the user has entered
                 // the same resource more than once.
             }
             $state[$user_phid] = array('phid' => $user_phid, 'role' => $resource['role'], 'owner' => $resource['owner']);
         }
         $all_phids = array_merge(array_keys($state), array_keys($affiliations));
         $all_phids = array_unique($all_phids);
         $delete_affiliations = array();
         $save_affiliations = array();
         foreach ($all_phids as $phid) {
             $old = idx($affiliations, $phid);
             $new = idx($state, $phid);
             if ($old && !$new) {
                 $delete_affiliations[] = $affiliations[$phid];
                 continue;
             }
             if (!$old) {
                 $affil = new PhabricatorProjectAffiliation();
                 $affil->setUserPHID($phid);
             } else {
                 $affil = $old;
             }
             $affil->setRole((string) $new['role']);
             $affil->setIsOwner((int) $new['owner']);
             $save_affiliations[] = $affil;
         }
         if (!$errors) {
             $project->save();
             $profile->setProjectPHID($project->getPHID());
             $profile->save();
             foreach ($delete_affiliations as $affil) {
                 $affil->delete();
             }
             foreach ($save_affiliations as $save) {
                 $save->setProjectPHID($project->getPHID());
                 $save->save();
             }
             return id(new AphrontRedirectResponse())->setURI('/project/view/' . $project->getID() . '/');
         } else {
             $phids = array_keys($state);
             $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
             foreach ($state as $phid => $info) {
                 $state[$phid]['name'] = $handles[$phid]->getFullName();
             }
         }
     } else {
         $phids = mpull($affiliations, 'getUserPHID');
         $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
         $state = array();
         foreach ($affiliations as $affil) {
             $user_phid = $affil->getUserPHID();
             $state[] = array('phid' => $user_phid, 'name' => $handles[$user_phid]->getFullName(), 'role' => $affil->getRole(), 'owner' => $affil->getIsOwner());
         }
     }
     $error_view = null;
     if ($errors) {
         $error_view = new AphrontErrorView();
         $error_view->setTitle('Form Errors');
         $error_view->setErrors($errors);
     }
     $header_name = 'Edit Project';
     $title = 'Edit Project';
     $action = '/project/edit/' . $project->getID() . '/';
     require_celerity_resource('project-edit-css');
     $form = new AphrontFormView();
     $form->setID('project-edit-form')->setUser($user)->setAction($action)->setEncType('multipart/form-data')->appendChild(id(new AphrontFormTextControl())->setLabel('Name')->setName('name')->setValue($project->getName())->setError($e_name))->appendChild(id(new AphrontFormSelectControl())->setLabel('Project Status')->setName('status')->setOptions($options)->setValue($project->getStatus()))->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Blurb')->setName('blurb')->setValue($profile->getBlurb()))->appendChild(id(new AphrontFormTokenizerControl())->setDatasource('/typeahead/common/projects/')->setLabel('Subprojects')->setName('set_subprojects')->setValue($subprojects))->appendChild(id(new AphrontFormMarkupControl())->setLabel('Profile Image')->setValue(phutil_render_tag('img', array('src' => $img_src))))->appendChild(id(new AphrontFormImageControl())->setLabel('Change Image')->setName('image')->setError($e_image)->setCaption('Supported formats: ' . implode(', ', $supported_formats)))->appendChild(id(new AphrontFormInsetView())->setTitle('Resources')->setRightButton(javelin_render_tag('a', array('href' => '#', 'class' => 'button green', 'sigil' => 'add-resource', 'mustcapture' => true), 'Add New Resource'))->appendChild(phutil_render_tag('input', array('type' => 'hidden', 'name' => 'resources', 'id' => 'resources')))->setContent(javelin_render_tag('table', array('sigil' => 'resources', 'class' => 'project-resource-table'), '')))->appendChild(id(new AphrontFormSubmitControl())->addCancelButton('/project/view/' . $project->getID() . '/')->setValue('Save'));
     $template = new AphrontTokenizerTemplateView();
     $template = $template->render();
     Javelin::initBehavior('projects-resource-editor', array('root' => 'project-edit-form', 'tokenizerTemplate' => $template, 'tokenizerSource' => '/typeahead/common/users/', 'input' => 'resources', 'state' => array_values($state)));
     $panel = new AphrontPanelView();
     $panel->setHeader($header_name);
     $panel->setWidth(AphrontPanelView::WIDTH_WIDE);
     $panel->appendChild($form);
     return $this->buildStandardPageResponse(array($error_view, $panel), array('title' => $title));
 }
 /**
  * Returns 'join' if this transaction causes the acting user ONLY to join the
  * project.
  *
  * Returns 'leave' if this transaction causes the acting user ONLY to leave
  * the project.
  *
  * Returns null in all other cases.
  */
 private function isJoinOrLeaveTransaction(PhabricatorProjectTransaction $xaction)
 {
     $type = $xaction->getTransactionType();
     if ($type != PhabricatorProjectTransactionType::TYPE_MEMBERS) {
         return null;
     }
     switch ($type) {
         case PhabricatorProjectTransactionType::TYPE_MEMBERS:
             $old = $xaction->getOldValue();
             $new = $xaction->getNewValue();
             $add = array_diff($new, $old);
             $rem = array_diff($old, $new);
             if (count($add) > 1) {
                 return null;
             } else {
                 if (count($add) == 1) {
                     if (reset($add) != $this->user->getPHID()) {
                         return null;
                     } else {
                         return 'join';
                     }
                 }
             }
             if (count($rem) > 1) {
                 return null;
             } else {
                 if (count($rem) == 1) {
                     if (reset($rem) != $this->user->getPHID()) {
                         return null;
                     } else {
                         return 'leave';
                     }
                 }
             }
             break;
     }
     return true;
 }
 private function transactionHasEffect(PhabricatorProjectTransaction $xaction)
 {
     return $xaction->getOldValue() !== $xaction->getNewValue();
 }