Commit 6b3df6be authored by Carsten  Rose's avatar Carsten Rose
Browse files

#5023 / Fabric: Cut, rotate and enhance uploaded images

DatabaseUpdateData.php: extend FormElement.type to 'imageCut'.
Support.php: extend joinPath() to join path parts optionally without using file as absolute path. Implement unit tests.
Download.php: doc
AbstractBuildForm.php: implement FE,typ=imageCut
formEditor.sql: update FE with new element imageCut.
parent 256b60c1
......@@ -121,6 +121,7 @@ abstract class AbstractBuildForm {
FE_TYPE_SUBRECORD => 'Subrecord',
FE_TYPE_UPLOAD => 'File',
FE_TYPE_ANNOTATE => 'Annotate',
FE_TYPE_IMAGE_CUT => 'ImageCut',
'fieldset' => 'Fieldset',
'pill' => 'Pill',
'templateGroup' => 'TemplateGroup',
......@@ -145,6 +146,7 @@ abstract class AbstractBuildForm {
FE_TYPE_SUBRECORD => 'Subrecord',
FE_TYPE_UPLOAD => 'Native',
FE_TYPE_ANNOTATE => 'Native',
FE_TYPE_IMAGE_CUT => 'Native',
'fieldset' => 'Fieldset',
'pill' => 'Pill',
'templateGroup' => 'TemplateGroup',
......@@ -196,7 +198,9 @@ abstract class AbstractBuildForm {
// <form>
if ($mode === FORM_LOAD) {
$htmlHead = $this->head();
if (count(OnArray::filter($this->feSpecNative, FE_TYPE, FE_TYPE_ANNOTATE)) > 0) {
if ((count(OnArray::filter($this->feSpecNative, FE_TYPE, FE_TYPE_ANNOTATE)) > 0) ||
(count(OnArray::filter($this->feSpecNative, FE_TYPE, FE_TYPE_IMAGE_CUT)) > 0)
) {
$flagFabric = true;
}
}
......@@ -2894,7 +2898,7 @@ abstract class AbstractBuildForm {
}
/**
* Build an Upload (File) Button.
* Build a Fabric Annotate Element
*
* @param array $formElement
* @param string $htmlFormElementName
......@@ -2938,6 +2942,76 @@ abstract class AbstractBuildForm {
$html = $htmlImage . $htmlFabric . $htmlInput . $this->getHelpBlock();
// $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
return $html;
}
/**
* Build a Fabric ImageCut Element
*
* @param array $formElement
* @param string $htmlFormElementName
* @param string $value
* @param array $json
* @param string $mode FORM_LOAD | FORM_UPDATE | FORM_SAVE
*
* @return string
* @throws CodeException
* @throws \qfq\UserFormException
*/
public function buildImageCut(array $formElement, $htmlFormElementName, $value, array &$json, $mode = FORM_LOAD) {
$htmlImage = '';
if ($mode == FORM_LOAD && !empty($formElement[FE_IMAGE_SOURCE])) {
if (!is_readable($formElement[FE_IMAGE_SOURCE])) {
throw new UserFormException("Error reading file: " . $formElement[FE_IMAGE_SOURCE], ERROR_IO_READ_FILE);
}
}
$htmlFabricId = $formElement[FE_HTML_ID];
$htmlFabricImageId = $formElement[FE_HTML_ID] . '-image';
//TODO: replace 'filename' by download via SIP
$imageFileName = support::joinPath($this->store->getVar(SYSTEM_BASE_URL_PRINT, STORE_SYSTEM), $value, PATH_FILE_CONCAT);
$imageFileName = $value;
// <div class="fabric"
// data-buttons="mockData/fabric.editor.buttons.json"
// data-edit-image="true"
// data-background-image="mockData/Scan2a.jpeg"
// data-control-name='fabric-output'
// data-image-resize-width="1200"
// data-image-output="target-png">
// </div>
$attributeFabric = Support::doAttribute('class', FABRIC_CSS_CLASS);
$attributeFabric .= Support::doAttribute('data-buttons', 'typo3conf/ext/qfq/Resources/Public/Json/fabric.editor.buttons.json');
$attributeFabric .= Support::doAttribute('data-edit-image', 'true');
$attributeFabric .= Support::doAttribute('data-background-image', $imageFileName);
$attributeFabric .= Support::doAttribute('data-control-name', $htmlFabricId);
// TODO: replace by user defined content
$attributeFabric .= Support::doAttribute('data-image-resize-width', '1200');
$attributeFabric .= Support::doAttribute('data-image-output', $htmlFabricImageId);
$attributeFabric .= $this->getAttributeFeMode($formElement[FE_MODE]);
$htmlFabric = Support::wrapTag('<div ' . $attributeFabric . ' >', '', false);
// <input id="fabric-output" name="fabric-data" type="hidden">
$attributeInput = Support::doAttribute('id', $htmlFabricId);
$attributeInput .= Support::doAttribute('name', $htmlFormElementName);
$attributeInput .= Support::doAttribute('type', 'hidden');
$htmlInput = Support::wrapTag('<input ' . $attributeInput . ' >', '', false);
// <img id="target-png">
$attributeImage = Support::doAttribute('id', $htmlFabricImageId);
$htmlImage = Support::wrapTag('<img ' . $attributeImage . '>', '', false);
$html = $htmlFabric . $this->getHelpBlock() . $htmlInput . $htmlImage;
// $tmpUrlParam[DOWNLOAD_MODE] = $this->getDownloadModeNCheck($vars);
// $tmpUrlParam[DOWNLOAD_EXPORT_FILENAME] = $vars[NAME_DOWNLOAD];
// $tmpUrlParam[SIP_DOWNLOAD_PARAMETER] = base64_encode(implode(PARAM_DELIMITER, $vars[NAME_DOWNLOAD_ELEMENTS]));
// $vars[NAME_URL_PARAM] = KeyValueStringParser::unparse($tmpUrlParam, '=', '&');
// $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
return $html;
......
......@@ -974,6 +974,7 @@ const FE_TYPE_RADIO = 'radio';
const FE_TYPE_SELECT = 'select';
const FE_TYPE_UPLOAD = 'upload';
const FE_TYPE_ANNOTATE = 'annotate';
const FE_TYPE_IMAGE_CUT = 'imageCut';
const FE_TYPE_EXTRA = 'extra';
const FE_TYPE_SUBRECORD = 'subrecord';
const FE_TYPE_NOTE = 'note';
......@@ -1062,6 +1063,9 @@ const FILE_ACTION = 'action';
const FILE_ACTION_UPLOAD = 'upload';
const FILE_ACTION_DELETE = 'delete';
const PATH_FILE_CONCAT = 'pathFileConcat';
const FILE_PRIORITY = 'filePriority';
// DATABASE
const DB_NUM_ROWS = 'numRows';
const DB_AFFECTED_ROWS = 'affectedRows';
......
......@@ -94,6 +94,9 @@ $UPDATE_ARRAY = array(
"ALTER TABLE `MailLog` CHANGE `attach` `attach` VARCHAR(1024) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT ''",
],
'0.25.10' => [
"ALTER TABLE `FormElement` CHANGE `type` `type` ENUM( 'checkbox', 'date', 'datetime', 'dateJQW', 'datetimeJQW', 'extra', 'gridJQW', 'text', 'editor', 'annotate', 'imageCut', 'time', 'note', 'password', 'radio', 'select', 'subrecord', 'upload', 'fieldset', 'pill', 'templateGroup', 'beforeLoad', 'beforeSave', 'beforeInsert', 'beforeUpdate', 'beforeDelete', 'afterLoad', 'afterSave', 'afterInsert', 'afterUpdate', 'afterDelete', 'sendMail', 'paste' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'text';",
],
);
......
......@@ -833,15 +833,32 @@ class Support {
}
/**
* Join $path and $file.
*
* @param $path
* @param $file
* @param string $path
* @param string $file
* @param string $mode FILE_PRIORITY | PATH_FILE_CONCAT
* @return string
*/
public static function joinPath($path, $file) {
public static function joinPath($path, $file, $mode = FILE_PRIORITY) {
if ($file == '') {
return $path;
}
if ($path == '') {
return $file;
}
if ($file[0] == DIRECTORY_SEPARATOR) {
if ($mode == FILE_PRIORITY) {
return $file; // absolute
} else {
if ($path != '') {
$file = substr($file, 1);
}
}
}
if (substr($path, -1) == DIRECTORY_SEPARATOR) {
......
......@@ -30,6 +30,8 @@ require_once(__DIR__ . '/../exceptions/DownloadException.php');
/**
* Class Download
*
* Documentation: PROTOCOL.md >> Download
*
* Param: i=1..n
* <i>_mode=direct | html2pdf
* <i>_id=<pageId>
......@@ -350,7 +352,6 @@ class Download {
return $filename;
}
/**
* Process download as requested in $vars. Output is either directly send to the browser, or a file which has to be deleted later.
*
......
......@@ -77,8 +77,8 @@ CREATE TABLE IF NOT EXISTS `FormElement` (
`modeSql` TEXT NOT NULL,
`class` ENUM('native', 'action', 'container') NOT NULL DEFAULT 'native',
`type` ENUM('checkbox', 'date', 'datetime', 'dateJQW', 'datetimeJQW', 'extra', 'gridJQW', 'text',
'editor', 'time', 'note', 'password', 'radio', 'select', 'subrecord', 'upload', 'annotate',
'fieldset', 'pill', 'templateGroup',
'editor', 'time', 'note', 'password', 'radio', 'select', 'subrecord', 'upload',
'annotate', 'imageCut', 'fieldset', 'pill', 'templateGroup',
'beforeLoad', 'beforeSave', 'beforeInsert', 'beforeUpdate', 'beforeDelete', 'afterLoad',
'afterSave', 'afterInsert', 'afterUpdate', 'afterDelete', 'sendMail', 'paste') NOT NULL DEFAULT 'text',
`subrecordOption` SET('edit', 'delete', 'new') NOT NULL DEFAULT '',
......@@ -303,9 +303,9 @@ VALUES
(2, 'class', 'Class', 'show', 'select', 'all', 'native', 180, 0, 0, '<a href="{{DOCUMENTATION_QFQ:Y}}#class-container">Info</a>', '', '{{class:FSRD0:alnumx}}', '', '', 100, '', 'yes', '', '', '', '', '', 'none'),
(2, 'type', 'Type', 'show', 'select', 'all', 'native', 190, 0, 0,
'<a href="{{DOCUMENTATION_QFQ:Y}}#class-native">native</a>, <a href="{{DOCUMENTATION_QFQ:Y}}#class-action">Action</a>, <a href="{{DOCUMENTATION_QFQ:Y}}#class-container">Container</a>',
'<a href="{{DOCUMENTATION_QFQ:Y}}#class-native">Native</a>, <a href="{{DOCUMENTATION_QFQ:Y}}#class-action">Action</a>, <a href="{{DOCUMENTATION_QFQ:Y}}#class-container">Container</a>',
'', '', '',
'itemList={{SELECT IF( "{{class:FRD0:alnumx}}"="native","checkbox,date,time,datetime,dateJQW,datetimeJQW,extra,gridJQW,text,editor,annotate,note,password,radio,select,subrecord,upload", IF("{{class:FRD0:alnumx}}"="action","beforeLoad,beforeSave,beforeInsert,beforeUpdate,beforeDelete,afterLoad,afterSave,afterInsert,afterUpdate,afterDelete,sendMail,paste", "fieldset,pill,templateGroup") ) }}',
'itemList={{SELECT IF( "{{class:FRD0:alnumx}}"="native","checkbox,date,time,datetime,dateJQW,datetimeJQW,extra,gridJQW,text,editor,annotate,imageCut,note,password,radio,select,subrecord,upload", IF("{{class:FRD0:alnumx}}"="action","beforeLoad,beforeSave,beforeInsert,beforeUpdate,beforeDelete,afterLoad,afterSave,afterInsert,afterUpdate,afterDelete,sendMail,paste", "fieldset,pill,templateGroup") ) }}',
100, '', 'yes', '', '', '', '', '', 'specialchar'),
(2, 'subrecordOption', 'Subrecord Option', 'show', 'checkbox', 'all', 'native', 200, 0, 0, '<a href="{{DOCUMENTATION_QFQ:Y}}#subrecord-option">Info</a>', '', '', '',
'', 100, '', 'yes', '', '', '', '{{ SELECT IF("{{type:FRE:alnumx}}"="subrecord" AND "{{class:FRE:alnumx}}"="native", "show", "hidden") }}', '', 'specialchar'),
......
......@@ -602,6 +602,76 @@ class SupportTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals("te > st", Support::htmlEntityEncodeDecode(MODE_DECODE, "te &gt; st"));
}
public function testJoinPath() {
$this->assertEquals('', Support::joinPath('', ''));
$this->assertEquals('etc', Support::joinPath('etc', ''));
$this->assertEquals('file', Support::joinPath('', 'file'));
$this->assertEquals('/etc', Support::joinPath('/etc', ''));
$this->assertEquals('/file', Support::joinPath('', '/file'));
$this->assertEquals('etc/', Support::joinPath('etc/', ''));
$this->assertEquals('file/', Support::joinPath('', 'file/'));
$this->assertEquals('/etc/', Support::joinPath('/etc/', ''));
$this->assertEquals('/file/', Support::joinPath('', '/file/'));
$this->assertEquals('etc/file', Support::joinPath('etc', 'file'));
$this->assertEquals('/etc/file', Support::joinPath('/etc', 'file'));
$this->assertEquals('/file', Support::joinPath('etc', '/file'));
$this->assertEquals('/file', Support::joinPath('/etc', '/file'));
$this->assertEquals('/file', Support::joinPath('/etc/', '/file'));
$this->assertEquals('/file/', Support::joinPath('/etc/', '/file/'));
$this->assertEquals('/etc/etc2/file/file2', Support::joinPath('/etc/etc2', 'file/file2'));
$this->assertEquals('/etc/etc2/file/file2', Support::joinPath('/etc/etc2/', 'file/file2'));
$this->assertEquals('/file/file2', Support::joinPath('/etc/etc2/', '/file/file2'));
#--
$this->assertEquals('', Support::joinPath('', '', FILE_PRIORITY));
$this->assertEquals('etc', Support::joinPath('etc', '', FILE_PRIORITY));
$this->assertEquals('file', Support::joinPath('', 'file', FILE_PRIORITY));
$this->assertEquals('/etc', Support::joinPath('/etc', '', FILE_PRIORITY));
$this->assertEquals('/file', Support::joinPath('', '/file', FILE_PRIORITY));
$this->assertEquals('etc/', Support::joinPath('etc/', '', FILE_PRIORITY));
$this->assertEquals('file/', Support::joinPath('', 'file/', FILE_PRIORITY));
$this->assertEquals('/etc/', Support::joinPath('/etc/', '', FILE_PRIORITY));
$this->assertEquals('/file/', Support::joinPath('', '/file/', FILE_PRIORITY));
$this->assertEquals('etc/file', Support::joinPath('etc', 'file', FILE_PRIORITY));
$this->assertEquals('/etc/file', Support::joinPath('/etc', 'file', FILE_PRIORITY));
$this->assertEquals('/file', Support::joinPath('etc', '/file', FILE_PRIORITY));
$this->assertEquals('/file', Support::joinPath('/etc', '/file', FILE_PRIORITY));
$this->assertEquals('/file', Support::joinPath('/etc/', '/file', FILE_PRIORITY));
$this->assertEquals('/file/', Support::joinPath('/etc/', '/file/', FILE_PRIORITY));
$this->assertEquals('/etc/etc2/file/file2', Support::joinPath('/etc/etc2', 'file/file2', FILE_PRIORITY));
$this->assertEquals('/etc/etc2/file/file2', Support::joinPath('/etc/etc2/', 'file/file2', FILE_PRIORITY));
$this->assertEquals('/file/file2', Support::joinPath('/etc/etc2/', '/file/file2', FILE_PRIORITY));
#--
$this->assertEquals('', Support::joinPath('', '', PATH_FILE_CONCAT));
$this->assertEquals('etc', Support::joinPath('etc', '', PATH_FILE_CONCAT));
$this->assertEquals('file', Support::joinPath('', 'file', PATH_FILE_CONCAT));
$this->assertEquals('/etc', Support::joinPath('/etc', '', PATH_FILE_CONCAT));
$this->assertEquals('/file', Support::joinPath('', '/file', PATH_FILE_CONCAT));
$this->assertEquals('etc/', Support::joinPath('etc/', '', PATH_FILE_CONCAT));
$this->assertEquals('file/', Support::joinPath('', 'file/', PATH_FILE_CONCAT));
$this->assertEquals('/etc/', Support::joinPath('/etc/', '', PATH_FILE_CONCAT));
$this->assertEquals('/file/', Support::joinPath('', '/file/', PATH_FILE_CONCAT));
$this->assertEquals('etc/file', Support::joinPath('etc', 'file', PATH_FILE_CONCAT));
$this->assertEquals('/etc/file', Support::joinPath('/etc', 'file', PATH_FILE_CONCAT));
$this->assertEquals('etc/file', Support::joinPath('etc', '/file', PATH_FILE_CONCAT));
$this->assertEquals('/etc/file', Support::joinPath('/etc', '/file', PATH_FILE_CONCAT));
$this->assertEquals('/etc/file', Support::joinPath('/etc/', '/file', PATH_FILE_CONCAT));
$this->assertEquals('/etc/file/', Support::joinPath('/etc/', '/file/', PATH_FILE_CONCAT));
$this->assertEquals('/etc/etc2/file/file2', Support::joinPath('/etc/etc2', 'file/file2', PATH_FILE_CONCAT));
$this->assertEquals('/etc/etc2/file/file2', Support::joinPath('/etc/etc2/', 'file/file2', PATH_FILE_CONCAT));
$this->assertEquals('/etc/etc2/file/file2', Support::joinPath('/etc/etc2/', '/file/file2', PATH_FILE_CONCAT));
}
protected function setUp() {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment