Set Project Description via PHP-API

I’m doing an import from Trello and Conduit API is not able to do all the things I wanted, so I’m using PH objects in PHP directly. I’m able to create projects, set workboard, add workboard columns and migrate my cards from T => PH – but! I can’t figure out how to set the Description attribute on the Project. I looks like it’s a custom field (‘std:project:internal:description’) – but how do I set that ?

$proj = id(new PhabricatorProject())->loadOneWhere('name = %s', $b['name']);
$proj->setName('fdafdasfas')->save(); // works!
$proj->setDescription() // doesn't work -- but that's the idea of what I want

Do I need to use some Transaction or CustomField helper – which ones? I’ve been digging in the source (src/applications/project) for ages and can’t figure it out.

The CustomField API is fairly old and is difficult to work with directly. Here’s the “correct” way to do this:

<?php

require_once 'scripts/init/init-script.php';

$viewer = PhabricatorUser::getOmnipotentUser();
$project_id = 25;
$new_description = 'Example Description';
$acting_phid = id(new PhabricatorProjectApplication())->getPHID();

$project = id(new PhabricatorProjectQuery())
  ->setViewer($viewer)
  ->withIDs(array($project_id))
  ->executeOne();
if (!$project) {
  throw new Exception(
    pht(
      'Unable to load project "%s".',
      $project_id));
}

$xaction_template = $project->getApplicationTransactionTemplate();
$xactions = array();

$field_list = PhabricatorCustomField::getObjectFields(
  $project,
  PhabricatorCustomField::ROLE_APPLICATIONTRANSACTIONS);

$fields = $field_list->getFields();
$fields = mpull($fields, null, 'getFieldKey');

$field_key = 'std:project:internal:description';
$description_field = idx($fields, $field_key);
if (!$description_field) {
  throw new Exception(
    pht(
      'Project has no custom "description" field.'));
}

$field_list->readFieldsFromStorage($project);

$xactions[] = id(clone $xaction_template)
  ->setTransactionType($description_field->getApplicationTransactionType())
  ->setMetadataValue('customfield:key', $description_field->getFieldKey())
  ->setOldValue($description_field->getOldValueForApplicationTransactions())
  ->setNewValue($new_description);

$content_source = PhabricatorContentSource::newForSource(
  PhabricatorConsoleContentSource::SOURCECONST);

$editor = $project->getApplicationTransactionEditor()
  ->setActor($viewer)
  ->setActingAsPHID($acting_phid)
  ->setContentSource($content_source)
  ->setContinueOnNoEffect(true);

$editor->applyTransactions($project, $xactions);

It may be easier to call the Conduit API in-process by using ConduitCall than to go through all these steps. UserEnableConduitAPIMethod is an example of using a *.edit API method directly from within PHP.

See https://secure.phabricator.com/T13248 for some discussion of planned changes here.

Thanks! This was super helpful – but it’s not working on projects that don’t already have description set it throws a PhabricatorDataNotAttachedException. So, I’m digging around now in the PhabricatorEditEngine code to get this sorted.

Once you load the project, you must $proj->attachParentProject(); to get that data attached. I had also tried the ConduitAPI in-line as suggested – but that was throwing errors too (I forgot to save those tho).

Now I think I’ve got all my Trello stuff over, Boards+Description => Project; Lists => Columns, Cards => Tasks (+Labels=>Tags, Members=>People)

Sweet!

1 Like