@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<?php
2
3final class PhabricatorImageDocumentEngine
4 extends PhabricatorDocumentEngine {
5
6 const ENGINEKEY = 'image';
7
8 public function getViewAsLabel(PhabricatorDocumentRef $ref) {
9 return pht('View as Image');
10 }
11
12 protected function getDocumentIconIcon(PhabricatorDocumentRef $ref) {
13 return 'fa-file-image-o';
14 }
15
16 protected function getByteLengthLimit() {
17 return (1024 * 1024 * 64);
18 }
19
20 public function canDiffDocuments(
21 ?PhabricatorDocumentRef $uref = null,
22 ?PhabricatorDocumentRef $vref = null) {
23
24 // For now, we can only render a rich image diff if the documents have
25 // their data stored in Files already.
26
27 if ($uref && !$uref->getFile()) {
28 return false;
29 }
30
31 if ($vref && !$vref->getFile()) {
32 return false;
33 }
34
35 return true;
36 }
37
38 public function newEngineBlocks(
39 ?PhabricatorDocumentRef $uref = null,
40 ?PhabricatorDocumentRef $vref = null) {
41
42 if ($uref) {
43 $u_blocks = $this->newDiffBlocks($uref);
44 } else {
45 $u_blocks = array();
46 }
47
48 if ($vref) {
49 $v_blocks = $this->newDiffBlocks($vref);
50 } else {
51 $v_blocks = array();
52 }
53
54 return id(new PhabricatorDocumentEngineBlocks())
55 ->addBlockList($uref, $u_blocks)
56 ->addBlockList($vref, $v_blocks);
57 }
58
59 public function newBlockDiffViews(
60 PhabricatorDocumentRef $uref,
61 PhabricatorDocumentEngineBlock $ublock,
62 PhabricatorDocumentRef $vref,
63 PhabricatorDocumentEngineBlock $vblock) {
64
65 $u_content = $this->newBlockContentView($uref, $ublock);
66 $v_content = $this->newBlockContentView($vref, $vblock);
67
68 return id(new PhabricatorDocumentEngineBlockDiff())
69 ->setOldContent($u_content)
70 ->addOldClass('diff-image-cell')
71 ->setNewContent($v_content)
72 ->addNewClass('diff-image-cell');
73 }
74
75
76 private function newDiffBlocks(PhabricatorDocumentRef $ref) {
77 $blocks = array();
78
79 $file = $ref->getFile();
80
81 $image_view = phutil_tag(
82 'div',
83 array(
84 'class' => 'differential-image-stage',
85 ),
86 phutil_tag(
87 'img',
88 array(
89 'alt' => $file->getAltText(),
90 'src' => $file->getBestURI(),
91 )));
92
93 $hash = $file->getContentHash();
94
95 $blocks[] = id(new PhabricatorDocumentEngineBlock())
96 ->setBlockKey('1')
97 ->setDifferenceHash($hash)
98 ->setContent($image_view);
99
100 return $blocks;
101 }
102
103 protected function canRenderDocumentType(PhabricatorDocumentRef $ref) {
104 $file = $ref->getFile();
105 if ($file) {
106 return $file->isViewableImage();
107 }
108
109 $viewable_types = PhabricatorEnv::getEnvConfig('files.viewable-mime-types');
110 $viewable_types = array_keys($viewable_types);
111
112 $image_types = PhabricatorEnv::getEnvConfig('files.image-mime-types');
113 $image_types = array_keys($image_types);
114
115 return
116 $ref->hasAnyMimeType($viewable_types) &&
117 $ref->hasAnyMimeType($image_types);
118 }
119
120 protected function newDocumentContent(PhabricatorDocumentRef $ref) {
121 $file = $ref->getFile();
122 if ($file) {
123 $source_uri = $file->getViewURI();
124 } else {
125 // We could use a "data:" URI here. It's not yet clear if or when we'll
126 // have a ref but no backing file.
127 throw new PhutilMethodNotImplementedException();
128 }
129
130 $image = phutil_tag(
131 'img',
132 array(
133 'alt' => $file->getAltText(),
134 'src' => $source_uri,
135 ));
136
137 $linked_image = phutil_tag(
138 'a',
139 array(
140 'href' => $source_uri,
141 'rel' => 'noreferrer',
142 ),
143 $image);
144
145 $container = phutil_tag(
146 'div',
147 array(
148 'class' => 'document-engine-image',
149 ),
150 $linked_image);
151
152 return $container;
153 }
154
155}