Skip to content

Commit dfa1ba2

Browse files
committed
generic attachment form field/container
1 parent e5f3e8a commit dfa1ba2

2 files changed

Lines changed: 287 additions & 0 deletions

File tree

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<?php
2+
3+
namespace wcf\system\form\builder\container;
4+
5+
use wcf\data\IStorableObject;
6+
use wcf\data\object\type\ObjectTypeCache;
7+
use wcf\system\attachment\AttachmentHandler;
8+
use wcf\system\event\EventHandler;
9+
use wcf\system\form\builder\field\AttachmentFormField;
10+
11+
class AttachmentFormContainer extends FormContainer {
12+
/**
13+
* attachment form field
14+
* @var AttachmentFormField
15+
*/
16+
protected $attachmentField;
17+
18+
/**
19+
* attachment-related data used to create an `AttachmentHandler` object for the attachment
20+
* form field
21+
* @var null|array
22+
*/
23+
protected $attachmentData;
24+
25+
/**
26+
* id of the edited object
27+
* @var integer
28+
*/
29+
protected $objectId;
30+
31+
/**
32+
* id of the field itself
33+
* @var integer
34+
*/
35+
protected $fieldId;
36+
37+
/**
38+
* Sets the attachment-related data used to create an `AttachmentHandler` object for the
39+
* attachment form field. If no attachment data is set, attachments are not supported.
40+
*
41+
* By default, no attachment data is set.
42+
*
43+
* @param null|string $objectType name of attachment object type or `null` to unset previous attachment data
44+
* @param integer $parentObjectID id of the parent of the object the attachments belong to or `0` if no such parent exists
45+
* @return static this form container
46+
* @throws \BadMethodCallException if the attachment form field has already been initialized
47+
*/
48+
public function attachmentData($objectType = null, $parentObjectID = 0) {
49+
if ($this->attachmentField !== null) {
50+
throw new \BadMethodCallException("The attachment form field has already been initialized. Use the atatchment form field directly to manipulate attachment data.");
51+
}
52+
53+
if ($objectType === null) {
54+
$this->attachmentData = null;
55+
}
56+
else {
57+
if (ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.attachment.objectType', $objectType) === null) {
58+
throw new \InvalidArgumentException("Unknown attachment object type '{$objectType}'.");
59+
}
60+
61+
$this->attachmentData = [
62+
'objectType' => $objectType,
63+
'parentObjectID' => $parentObjectID
64+
];
65+
}
66+
67+
return $this;
68+
}
69+
70+
/**
71+
* Returns the form field handling attachments.
72+
*
73+
* @return AttachmentFormField
74+
* @throws \BadMethodCallException if the form field container has not been populated yet/form has not been built yet
75+
*/
76+
public function getAttachmentField() {
77+
if ($this->attachmentField === null) {
78+
throw new \BadMethodCallException("attachment form field can only be requested after the form has been built.");
79+
}
80+
81+
return $this->attachmentField;
82+
}
83+
84+
/**
85+
* Returns the id of the edited object or `0` if no object is edited.
86+
*
87+
* @return integer
88+
*/
89+
public function getObjectId() {
90+
return $this->objectId;
91+
}
92+
93+
/**
94+
* @inheritDoc
95+
*/
96+
public function id($id) {
97+
$this->fieldId = $id;
98+
99+
return parent::id($id . 'Container');
100+
}
101+
102+
/**
103+
* @inheritDoc
104+
*/
105+
public function loadValues(array $data, IStorableObject $object) {
106+
$this->objectId = $object->{$object::getDatabaseTableIndexName()};
107+
108+
if ($this->attachmentData !== null) {
109+
// updated attachment handler with object id
110+
$this->attachmentField->attachmentHandler(
111+
new AttachmentHandler(
112+
$this->attachmentData['objectType'],
113+
$this->getObjectId(),
114+
'.',
115+
$this->attachmentData['parentObjectID']
116+
)
117+
);
118+
}
119+
120+
return parent::loadValues($data, $object);
121+
}
122+
123+
/**
124+
* @inheritDoc
125+
*/
126+
public function populate() {
127+
parent::populate();
128+
129+
$this->attachmentField = AttachmentFormField::create($this->fieldId);
130+
131+
$this->appendChildren([
132+
$this->attachmentField
133+
]);
134+
135+
if ($this->attachmentData !== null) {
136+
$this->attachmentField->attachmentHandler(
137+
// the temporary hash may not be empty (at the same time as the
138+
// object id) and it will be changed anyway by the called method
139+
new AttachmentHandler(
140+
$this->attachmentData['objectType'],
141+
$this->getObjectId(),
142+
'.',
143+
$this->attachmentData['parentObjectID']
144+
)
145+
);
146+
}
147+
148+
EventHandler::getInstance()->fireAction($this, 'populate');
149+
}
150+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<?php
2+
3+
namespace wcf\system\form\builder\field;
4+
5+
use wcf\system\attachment\AttachmentHandler;
6+
use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
7+
use wcf\system\form\builder\IFormDocument;
8+
use wcf\system\WCF;
9+
use wcf\util\StringUtil;
10+
11+
class AttachmentFormField extends AbstractFormField {
12+
/**
13+
* attachment handler
14+
* @var null|AttachmentHandler
15+
*/
16+
protected $attachmentHandler;
17+
18+
/**
19+
* @inheritDoc
20+
*/
21+
protected $javaScriptDataHandlerModule = 'WoltLabSuite/Core/Form/Builder/Field/Wysiwyg/Attachment';
22+
23+
/**
24+
* @inheritDoc
25+
*/
26+
protected $templateName = '__wysiwygAttachmentFormField';
27+
28+
/**
29+
* Creates a new instance of `AttachmentFormField`.
30+
*/
31+
public function __construct() {
32+
$this->addClass('wide');
33+
}
34+
35+
/**
36+
* Sets the attachment handler object for the uploaded attachments. If `null` is given,
37+
* the previously set attachment handler is unset.
38+
*
39+
* For the initial attachment handler set by this method, the temporary hashes will be
40+
* automatically set by either reading them from the session variables if the form handles
41+
* AJAX requests or by creating a new one. If the temporary hashes are read from session,
42+
* the session variable will be unregistered afterwards.
43+
*
44+
* @param null|AttachmentHandler $attachmentHandler
45+
* @return static
46+
*/
47+
public function attachmentHandler(AttachmentHandler $attachmentHandler = null) {
48+
if ($attachmentHandler !== null) {
49+
if ($this->attachmentHandler === null) {
50+
$tmpHash = StringUtil::getRandomID();
51+
if ($this->getDocument()->isAjax()) {
52+
$sessionTmpHash = WCF::getSession()->getVar('__wcfAttachmentTmpHash');
53+
if ($sessionTmpHash !== null) {
54+
$tmpHash = $sessionTmpHash;
55+
56+
WCF::getSession()->unregister('__wcfAttachmentTmpHash');
57+
}
58+
}
59+
60+
$attachmentHandler->setTmpHashes([$tmpHash]);
61+
}
62+
else {
63+
// preserve temporary hashes
64+
$attachmentHandler->setTmpHashes($this->attachmentHandler->getTmpHashes());
65+
}
66+
}
67+
68+
$this->attachmentHandler = $attachmentHandler;
69+
70+
if ($this->attachmentHandler !== null) {
71+
$this->description('wcf.attachment.upload.limits', [
72+
'attachmentHandler' => $this->attachmentHandler
73+
]);
74+
}
75+
else {
76+
$this->description();
77+
}
78+
79+
return $this;
80+
}
81+
82+
/**
83+
* Returns the attachment handler object for the uploaded attachments or `null` if no attachment
84+
* upload is supported.
85+
*
86+
* @return null|AttachmentHandler
87+
*/
88+
public function getAttachmentHandler() {
89+
return $this->attachmentHandler;
90+
}
91+
92+
/**
93+
* @inheritDoc
94+
*/
95+
public function hasSaveValue() {
96+
return false;
97+
}
98+
99+
/**
100+
* @inheritDoc
101+
*/
102+
public function isAvailable() {
103+
return parent::isAvailable() && $this->getAttachmentHandler() !== null;
104+
}
105+
106+
/**
107+
* @inheritDoc
108+
*/
109+
public function populate() {
110+
parent::populate();
111+
112+
$this->getDocument()->getDataHandler()->addProcessor(new CustomFormDataProcessor($this->getId(), function(IFormDocument $document, array $parameters) {
113+
if ($this->getAttachmentHandler() !== null) {
114+
$parameters[$this->getId() . '_attachmentHandler'] = $this->getAttachmentHandler();
115+
}
116+
117+
return $parameters;
118+
}));
119+
120+
return $this;
121+
}
122+
123+
/**
124+
* @inheritDoc
125+
*/
126+
public function readValue() {
127+
if ($this->getDocument()->hasRequestData($this->getPrefixedId() . '_tmpHash')) {
128+
$tmpHash = $this->getDocument()->getRequestData($this->getPrefixedId() . '_tmpHash');
129+
if (is_string($tmpHash)) {
130+
$this->getAttachmentHandler()->setTmpHashes([$tmpHash]);
131+
}
132+
else if (is_array($tmpHash)) {
133+
$this->getAttachmentHandler()->setTmpHashes($tmpHash);
134+
}
135+
}
136+
}
137+
}

0 commit comments

Comments
 (0)