I've added custom fields to maniphest and they work fine, but when I try to add them to Projects, any item that uses storage enters an infinite loop when you try to save it.
=== Reproduce steps:
Place this file in `src/extensions`, and try to edit a project.
{P1201}
(As a note, I have no idea if setting the proxy in the constructor is the right way, but it seemed to work for maniphest task custom fields)
Results in the error:
```
>>> UNRECOVERABLE FATAL ERROR <<<
Maximum function nesting level of '100' reached, aborting!
/opt/code/phabricator/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php:62
┻━┻ ︵ ¯\_(ツ)_/¯ ︵ ┻━┻
```
=== More details
Xdebug shows that we are bouncing between [[ https://secure.phabricator.com/diffusion/P/browse/master/src/infrastructure/customfield/field/PhabricatorCustomField.php;b7a970598d7f4acfa9fffeab8124701678781183$524-526 | PhabricatorCustomField->newStorageObject() ]] and [[ https://secure.phabricator.com/diffusion/P/browse/master/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php;b7a970598d7f4acfa9fffeab8124701678781183$232-234 | PhabricatorStandardCustomField->newStorageObject() ]]
```
...
[3] file:///opt/code/phabricator/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php.PhabricatorStandardCustomField->newStorageObject:233
[4] file:///opt/code/phabricator/src/infrastructure/customfield/field/PhabricatorCustomField.php.PhabricatorCustomField->newStorageObject:526
[5] file:///opt/code/phabricator/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php.PhabricatorStandardCustomField->newStorageObject:233
[6] file:///opt/code/phabricator/src/infrastructure/customfield/field/PhabricatorCustomField.php.PhabricatorCustomField->newStorageObject:526
[7] file:///opt/code/phabricator/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php.PhabricatorStandardCustomField->newStorageObject:233
...
```
=== Solution
The solution I found was making PhabricatorProjectCustomField add some missing methods that were implemented in ManiphestCustomField:
```
public function newStorageObject() {
return new PhabricatorProjectCustomFieldStorage();
}
protected function newStringIndexStorage() {
return new PhabricatorProjectCustomFieldStringIndex();
}
protected function newNumericIndexStorage() {
return new PhabricatorProjectCustomFieldNumericIndex();
}
```
Diff incoming.