@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 119 lines 3.7 kB view raw
1<?php 2 3abstract class PhabricatorFileTransform extends Phobject { 4 5 abstract public function getTransformName(); 6 abstract public function getTransformKey(); 7 abstract public function canApplyTransform(PhabricatorFile $file); 8 abstract public function applyTransform(PhabricatorFile $file); 9 10 public function getDefaultTransform(PhabricatorFile $file) { 11 return null; 12 } 13 14 public function generateTransforms() { 15 return array($this); 16 } 17 18 /** 19 * Get an existing transformed file, or create a new transformed file if no 20 * transformed file already exists. 21 * If a new file is produced, it is connected to the original file 22 * in an explicit way, so, persisting a new 'PhabricatorTransformedFile' row. 23 * 24 * @param PhabricatorFile $file Original file. 25 * You must check yourself if the viewer has 26 * sufficient permissions to see this file. 27 * @return PhabricatorFile Transformed file 28 */ 29 public function getOrExecuteTransformExplicit(PhabricatorFile $file) { 30 // Use of omnipotent user is okay here because the assume 31 // the user can see the input $file, and so, its transforms. 32 // See PhabricatorFile::hasAutomaticCapability(). 33 $xformed_file = id(new PhabricatorFileQuery()) 34 ->setViewer(PhabricatorUser::getOmnipotentUser()) 35 ->withTransforms( 36 array( 37 array( 38 'originalPHID' => $file->getPHID(), 39 'transform' => $this->getTransformKey(), 40 ), 41 )) 42 ->executeOne(); 43 44 if ($xformed_file) { 45 return $xformed_file; 46 } 47 48 return $this->executeTransformExplicit($file); 49 } 50 51 /** 52 * Create a new transformed file. 53 * This usually causes the creation of a new 'PhabricatorFile'. 54 * 55 * @param PhabricatorFile $file Original file 56 * @return PhabricatorFile Transformed file 57 */ 58 public function executeTransform(PhabricatorFile $file) { 59 if ($this->canApplyTransform($file)) { 60 try { 61 return $this->applyTransform($file); 62 } catch (Exception $ex) { 63 // Ignore. 64 } 65 } 66 67 return $this->getDefaultTransform($file); 68 } 69 70 /** 71 * Wrapper of executeTransform() that also persists the relationship 72 * between the original file and the transform, if it makes sense to do so. 73 * 74 * @param PhabricatorFile $file Original file 75 * @return PhabricatorFile Transformed file 76 */ 77 public function executeTransformExplicit(PhabricatorFile $file) { 78 // This can be NULL. 79 $xform = $this->executeTransform($file); 80 81 // Connect the original file to its transform, if any. 82 // Skip transforms that are derived from a builtin as cautionary measure: 83 // - Builtins may have a lot of transforms. We don't know if the UX scales. 84 // Example page: /file/transforms/1/ 85 // - Tracking builtins gives unclear benefits. 86 if ($xform && !$file->isBuiltin()) { 87 id(new PhabricatorTransformedFile()) 88 ->setOriginalPHID($file->getPHID()) 89 ->setTransformedPHID($xform->getPHID()) 90 ->setTransform($this->getTransformKey()) 91 ->save(); 92 } 93 94 return $xform; 95 } 96 97 public static function getAllTransforms() { 98 return id(new PhutilClassMapQuery()) 99 ->setAncestorClass(self::class) 100 ->setExpandMethod('generateTransforms') 101 ->setUniqueMethod('getTransformKey') 102 ->execute(); 103 } 104 105 public static function getTransformByKey($key) { 106 $all = self::getAllTransforms(); 107 108 $xform = idx($all, $key); 109 if (!$xform) { 110 throw new Exception( 111 pht( 112 'No file transform with key "%s" exists.', 113 $key)); 114 } 115 116 return $xform; 117 } 118 119}