@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
at upstream/main 239 lines 7.1 kB view raw
1<?php 2 3final class PhabricatorFilesComposeIconBuiltinFile 4 extends PhabricatorFilesBuiltinFile { 5 6 private $icon; 7 private $color; 8 9 public function setIcon($icon) { 10 $this->icon = $icon; 11 return $this; 12 } 13 14 public function getIcon() { 15 return $this->icon; 16 } 17 18 public function setColor($color) { 19 $this->color = $color; 20 return $this; 21 } 22 23 public function getColor() { 24 return $this->color; 25 } 26 27 public function getBuiltinFileKey() { 28 $icon = $this->getIcon(); 29 $color = $this->getColor(); 30 $desc = "compose(icon={$icon}, color={$color})"; 31 $hash = PhabricatorHash::digestToLength($desc, 40); 32 return "builtin:{$hash}"; 33 } 34 35 public function getBuiltinDisplayName() { 36 $icon = $this->getIcon(); 37 $color = $this->getColor(); 38 return "{$icon}-{$color}.png"; 39 } 40 41 public function loadBuiltinFileData() { 42 return $this->composeImage($this->getColor(), $this->getIcon()); 43 } 44 45 public static function getAllIcons() { 46 $root = dirname(phutil_get_library_root('phabricator')); 47 $root = $root.'/resources/builtin/projects/'; 48 49 $quips = self::getIconQuips(); 50 51 $map = array(); 52 $list = Filesystem::listDirectory($root, $include_hidden = false); 53 foreach ($list as $file) { 54 $count = 0; 55 $short = preg_replace('/\.png$/', '', $file, -1, $count); 56 if ($count === 1) { 57 $map[$short] = array( 58 'path' => $root.$file, 59 'quip' => idx($quips, $short, $short), 60 ); 61 } 62 } 63 64 return $map; 65 } 66 67 public static function getAllColors() { 68 $colors = id(new CelerityResourceTransformer()) 69 ->getCSSVariableMap(); 70 71 $colors = array_select_keys( 72 $colors, 73 array( 74 'red', 75 'orange', 76 'yellow', 77 'green', 78 'blue', 79 'sky', 80 'indigo', 81 'violet', 82 'pink', 83 'charcoal', 84 'backdrop', 85 )); 86 87 $quips = self::getColorQuips(); 88 89 $map = array(); 90 foreach ($colors as $name => $color) { 91 $map[$name] = array( 92 'color' => $color, 93 'quip' => idx($quips, $name, $name), 94 ); 95 } 96 97 return $map; 98 } 99 100 private function composeImage($color, $icon) { 101 // If we don't have the GD extension installed, just return a static 102 // default project image rather than trying to compose one. 103 if (!function_exists('imagecreatefromstring')) { 104 $root = dirname(phutil_get_library_root('phabricator')); 105 $default_path = $root.'/resources/builtin/profile.png'; 106 return Filesystem::readFile($default_path); 107 } 108 109 $color_map = self::getAllColors(); 110 $color = idx($color_map, $color); 111 if (!$color) { 112 $fallback = 'backdrop'; 113 $color = idx($color_map, $fallback); 114 if (!$color) { 115 throw new Exception( 116 pht( 117 'Fallback compose color ("%s") does not exist!', 118 $fallback)); 119 } 120 } 121 122 $color_hex = idx($color, 'color'); 123 $color_const = hexdec(trim($color_hex, '#')); 124 125 $icon_map = self::getAllIcons(); 126 $icon = idx($icon_map, $icon); 127 if (!$icon) { 128 $fallback = 'fa-umbrella'; 129 $icon = idx($icon_map, $fallback); 130 if (!$icon) { 131 throw new Exception( 132 pht( 133 'Fallback compose icon ("%s") does not exist!', 134 $fallback)); 135 } 136 } 137 138 $path = idx($icon, 'path'); 139 $data = Filesystem::readFile($path); 140 141 $icon_img = imagecreatefromstring($data); 142 143 $canvas = imagecreatetruecolor(200, 200); 144 imagefill($canvas, 0, 0, $color_const); 145 imagecopy($canvas, $icon_img, 0, 0, 0, 0, 200, 200); 146 147 return PhabricatorImageTransformer::saveImageDataInAnyFormat( 148 $canvas, 149 'image/png'); 150 } 151 152 private static function getIconQuips() { 153 return array( 154 'fa-android' => pht('Friendly Robot'), 155 'fa-apple' => pht('Friendly Fruit'), 156 'fa-beer' => pht('Liquid Carbs'), 157 'fa-bomb' => pht('Boom!'), 158 'fa-book' => pht('Read Me'), 159 'fa-briefcase' => pht('Briefcase'), 160 'fa-bug' => pht('Bug'), 161 'fa-building' => pht('Company'), 162 'fa-calendar' => pht('Deadline'), 163 'fa-camera-retro' => pht('Leica Enthusiast'), 164 'fa-chrome' => pht('Shiny'), 165 'fa-cloud' => pht('The Cloud'), 166 'fa-coffee' => pht('Go Juice'), 167 'fa-comments' => pht('Cartoon Captions'), 168 'fa-credit-card' => pht('Accounting'), 169 'fa-database' => pht('Stack of Pancakes'), 170 'fa-desktop' => pht('Cardboard Box'), 171 'fa-diamond' => pht('Isometric-Hexoctahedral'), 172 'fa-empire' => pht('Bad Guys'), 173 'fa-envelope' => pht('Communication'), 174 'fa-facebook' => pht('College Site'), 175 'fa-fax' => pht('Communication Device'), 176 'fa-film' => pht('Physical Film'), 177 'fa-firefox' => pht('Blake Ross'), 178 'fa-flag-checkered' => pht('Goal'), 179 'fa-flask' => pht('Experimental'), 180 'fa-folder' => pht('Folder'), 181 'fa-gamepad' => pht('Half-Life 3 Confirmed'), 182 'fa-gears' => pht('Mechanical'), 183 'fa-google' => pht('Car Company'), 184 'fa-hand-peace-o' => pht('Peace'), 185 'fa-hashtag' => pht('Not Slack'), 186 'fa-heart' => pht('Myocardial Infarction'), 187 'fa-internet-explorer' => pht('Now Just Edge'), 188 'fa-key' => pht('Primitive Security'), 189 'fa-legal' => pht('Hired Protection'), 190 'fa-linux' => pht('M\'Lady'), 191 'fa-lock' => pht('Policy'), 192 'fa-map-marker' => pht('Destination Beacon'), 193 'fa-microphone' => pht('Podcasting'), 194 'fa-mobile' => pht('Tiny Pocket Cat Meme Machine'), 195 'fa-money' => pht('1 of 99 Problems'), 196 'fa-phone' => pht('Grandma Uses This'), 197 'fa-pie-chart' => pht('Not Actually Edible'), 198 'fa-rebel' => pht('Good Guys'), 199 'fa-reddit-alien' => pht('Updoot In 5 Seconds'), 200 'fa-safari' => pht('Fruit Exploration'), 201 'fa-search' => pht('Dust Detector'), 202 'fa-server' => pht('Heating Units'), 203 'fa-shopping-cart' => pht('Buy Stuff'), 204 'fa-sitemap' => pht('Sitemap'), 205 'fa-star' => pht('The More You Know'), 206 'fa-tablet' => pht('Cellular Telephone For Giants'), 207 'fa-tag' => pht('You\'re It'), 208 'fa-tags' => pht('Tags'), 209 'fa-trash-o' => pht('Garbage'), 210 'fa-truck' => pht('Release'), 211 'fa-twitter' => pht('Bird Stencil'), 212 'fa-umbrella' => pht('An Umbrella'), 213 'fa-university' => pht('School'), 214 'fa-user-secret' => pht('Shhh'), 215 'fa-user' => pht('Individual'), 216 'fa-users' => pht('Team'), 217 'fa-warning' => pht('No Caution Required, Everything Looks Safe'), 218 'fa-wheelchair' => pht('Accessibility'), 219 'fa-windows' => pht('Windows'), 220 ); 221 } 222 223 private static function getColorQuips() { 224 return array( 225 'red' => pht('Verbillion'), 226 'orange' => pht('Navel Orange'), 227 'yellow' => pht('Prim Goldenrod'), 228 'green' => pht('Lustrous Verdant'), 229 'blue' => pht('Tropical Deep'), 230 'sky' => pht('Wide Open Sky'), 231 'indigo' => pht('Pleated Khaki'), 232 'violet' => pht('Aged Merlot'), 233 'pink' => pht('Easter Bunny'), 234 'charcoal' => pht('Gemstone'), 235 'backdrop' => pht('Driven Snow'), 236 ); 237 } 238 239}