@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at recaptime-dev/main 180 lines 5.9 kB view raw
1<?php 2 3final class PhabricatorSystemRemoveDestroyWorkflow 4 extends PhabricatorSystemRemoveWorkflow { 5 6 protected function didConstruct() { 7 $this 8 ->setName('destroy') 9 ->setSynopsis(pht('Permanently destroy objects.')) 10 ->setExamples('**destroy** [__options__] __object__ ...') 11 ->setArguments( 12 array( 13 array( 14 'name' => 'force', 15 'help' => pht('Destroy objects without prompting.'), 16 ), 17 array( 18 'name' => 'objects', 19 'wildcard' => true, 20 ), 21 )); 22 } 23 24 public function execute(PhutilArgumentParser $args) { 25 $console = PhutilConsole::getConsole(); 26 27 $object_names = $args->getArg('objects'); 28 if (!$object_names) { 29 throw new PhutilArgumentUsageException( 30 pht('Specify one or more objects to destroy.')); 31 } 32 33 $object_query = id(new PhabricatorObjectQuery()) 34 ->setViewer($this->getViewer()) 35 ->withNames($object_names); 36 37 $object_query->execute(); 38 39 $named_objects = $object_query->getNamedResults(); 40 foreach ($object_names as $object_name) { 41 if (empty($named_objects[$object_name])) { 42 throw new PhutilArgumentUsageException( 43 pht('No such object "%s" exists!', $object_name)); 44 } 45 } 46 47 foreach ($named_objects as $object_name => $object) { 48 if (!($object instanceof PhabricatorDestructibleInterface)) { 49 throw new PhutilArgumentUsageException( 50 pht( 51 'Object "%s" can not be destroyed (it does not implement %s).', 52 $object_name, 53 'PhabricatorDestructibleInterface')); 54 } 55 } 56 57 $banner = <<<EOBANNER 58 uuuuuuu 59 uu###########uu 60 uu#################uu 61 u#####################u 62 u#######################u 63 u#########################u 64 u#########################u 65 u######" "###" "######u 66 "####" u#u ####" 67 ###u u#u u### 68 ###u u###u u### 69 "####uu### ###uu####" 70 "#######" "#######" 71 u#######u#######u 72 u#"#"#"#"#"#"#u 73 uuu ##u# # # # #u## uuu 74 u#### #####u#u#u### u#### 75 #####uu "#########" uu###### 76 u###########uu """"" uuuu########## 77 ####"""##########uuu uu#########"""###" 78 """ ""###########uu ""#""" 79 uuuu ""##########uuu 80 u###uuu#########uu ""###########uuu### 81 ##########"""" ""###########" 82 "#####" ""####"" 83 ###" ####" 84 85EOBANNER; 86 87 88 $console->writeOut("\n\n<fg:red>%s</fg>\n\n", $banner); 89 90 $console->writeOut( 91 "<bg:red>** %s **</bg> %s\n\n%s\n\n". 92 "<bg:red>** %s **</bg> %s\n\n%s\n\n", 93 pht('IMPORTANT'), 94 pht('DATA WILL BE PERMANENTLY DESTROYED'), 95 phutil_console_wrap( 96 pht( 97 'Objects will be permanently destroyed. There is no way to '. 98 'undo this operation or ever retrieve this data unless you '. 99 'maintain external backups.')), 100 pht('IMPORTANT'), 101 pht('DELETING OBJECTS OFTEN BREAKS THINGS'), 102 phutil_console_wrap( 103 pht( 104 'Destroying objects may cause related objects to stop working, '. 105 'and may leave scattered references to objects which no longer '. 106 'exist. In most cases, it is much better to disable or archive '. 107 'objects instead of destroying them. This risk is greatest when '. 108 'deleting complex or highly connected objects like repositories, '. 109 'projects and users.'. 110 "\n\n". 111 'These tattered edges are an expected consequence of destroying '. 112 'objects, and the upstream will not help you fix them. We '. 113 'strongly recommend disabling or archiving objects instead.'))); 114 115 $phids = mpull($named_objects, 'getPHID'); 116 $handles = PhabricatorUser::getOmnipotentUser()->loadHandles($phids); 117 118 $console->writeOut( 119 pht( 120 'These %s object(s) will be destroyed forever:', 121 phutil_count($named_objects))."\n\n"); 122 123 foreach ($named_objects as $object_name => $object) { 124 $phid = $object->getPHID(); 125 126 $console->writeOut( 127 " - %s (%s) %s\n", 128 $object_name, 129 get_class($object), 130 $handles[$phid]->getFullName()); 131 } 132 133 $force = $args->getArg('force'); 134 if (!$force) { 135 $ok = $console->confirm( 136 pht( 137 'Are you absolutely certain you want to destroy these %s object(s)?', 138 phutil_count($named_objects))); 139 if (!$ok) { 140 throw new PhutilArgumentUsageException( 141 pht('Aborted, your objects are safe.')); 142 } 143 } 144 145 $console->writeOut("%s\n", pht('Destroying objects...')); 146 147 $notes = array(); 148 foreach ($named_objects as $object_name => $object) { 149 $console->writeOut( 150 pht( 151 "Destroying %s **%s**...\n", 152 get_class($object), 153 $object_name)); 154 155 $engine = id(new PhabricatorDestructionEngine()) 156 ->setCollectNotes(true); 157 158 $engine->destroyObject($object); 159 160 foreach ($engine->getNotes() as $note) { 161 $notes[] = $note; 162 } 163 } 164 165 $console->writeOut( 166 "%s\n", 167 pht( 168 'Permanently destroyed %s object(s).', 169 phutil_count($named_objects))); 170 171 if ($notes) { 172 id(new PhutilConsoleList()) 173 ->addItems($notes) 174 ->draw(); 175 } 176 177 return 0; 178 } 179 180}