Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
S
sg_youtube
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Model registry
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
TYPO3
sg_youtube
Commits
f98cb4cb
Commit
f98cb4cb
authored
1 year ago
by
Johannes Kreiner
Browse files
Options
Downloads
Patches
Plain Diff
[TASK] Update RenderSvgViewHelper
parent
ef538968
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
Classes/ViewHelpers/RenderSvgViewHelper.php
+155
-98
155 additions, 98 deletions
Classes/ViewHelpers/RenderSvgViewHelper.php
with
155 additions
and
98 deletions
Classes/ViewHelpers/RenderSvgViewHelper.php
+
155
−
98
View file @
f98cb4cb
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
* All rights reserved
* All rights reserved
*
*
* This script is part of the
AY
project. The
AY
project is
* This script is part of the
TYPO3
project. The
TYPO3
project is
* free software; you can redistribute it and/or modify
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* the Free Software Foundation; either version 3 of the License, or
...
@@ -26,6 +26,8 @@
...
@@ -26,6 +26,8 @@
namespace
SGalinski\SgYoutube\ViewHelpers
;
namespace
SGalinski\SgYoutube\ViewHelpers
;
use
Exception
;
use
SimpleXMLElement
;
use
TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper
;
use
TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper
;
/**
/**
...
@@ -39,7 +41,18 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
...
@@ -39,7 +41,18 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
* @api
* @api
*/
*/
protected
$tagName
=
'svg'
;
protected
$tagName
=
'svg'
;
protected
$xmlInfo
=
'<?xml version="1.0"?>'
;
/**
* @var array
*/
protected
static
array
$svgInstances
=
[];
/**
* The directory path where the SVGs are located
*
* @var string
*/
protected
$directoryPath
=
__DIR__
.
'/../../Resources/Public/Icons/'
;
protected
$directoryPath
=
__DIR__
.
'/../../Resources/Public/Icons/'
;
/**
/**
...
@@ -47,39 +60,77 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
...
@@ -47,39 +60,77 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
*/
*/
public
function
initializeArguments
():
void
{
public
function
initializeArguments
():
void
{
parent
::
initializeArguments
();
parent
::
initializeArguments
();
$this
->
registerArgument
(
'name'
,
'string'
,
'The SVG name'
,
TRUE
);
$this
->
registerArgument
(
$this
->
registerArgument
(
'color'
,
'string'
,
'The fill color'
,
TRUE
);
'name'
,
$this
->
registerArgument
(
'id'
,
'string'
,
'The HTML id attribute'
,
FALSE
);
'string'
,
$this
->
registerArgument
(
'path'
,
'string'
,
'Path to the SVG file if not in default'
,
FALSE
);
'The SVG name, also supports folders (e.g. fontawesome/solid/ad)'
,
$this
->
registerArgument
(
'class'
,
'string'
,
'The HTML class attribute'
,
FALSE
);
TRUE
$this
->
registerArgument
(
'title'
,
'string'
,
'The HTML title attribute'
,
FALSE
);
);
$this
->
registerArgument
(
'width'
,
'string'
,
'The HTML width attribute'
,
FALSE
);
$this
->
registerArgument
(
$this
->
registerArgument
(
'height'
,
'string'
,
'The HTML height attribute'
,
FALSE
);
'color'
,
$this
->
registerArgument
(
'style'
,
'string'
,
'Inline CSS styles'
,
FALSE
);
'string'
,
$this
->
registerArgument
(
'use'
,
'string'
,
'Inline CSS styles'
,
FALSE
);
'The color'
,
FALSE
,
'currentColor'
);
$this
->
registerArgument
(
'colorAttribute'
,
'string'
,
'The color target to affect: fill, stroke. Leave empty for both'
);
$this
->
registerArgument
(
'id'
,
'string'
,
'The HTML id attribute'
);
$this
->
registerArgument
(
'path'
,
'string'
,
'Path to the SVG file if not in default'
);
$this
->
registerArgument
(
'class'
,
'string'
,
'The HTML class attribute'
);
$this
->
registerArgument
(
'title'
,
'string'
,
'The HTML title attribute'
);
$this
->
registerArgument
(
'width'
,
'string'
,
'The HTML width attribute'
);
$this
->
registerArgument
(
'height'
,
'string'
,
'The HTML height attribute'
);
$this
->
registerArgument
(
'viewBox'
,
'string'
,
'The HTML viewBox attribute'
);
$this
->
registerArgument
(
'viewBoxOnly'
,
'boolean'
,
'If only the viewBox attribute should be used instead of width/height'
);
$this
->
registerArgument
(
'stroke-width'
,
'string'
,
'The HTML stroke-width attribute'
);
$this
->
registerArgument
(
'style'
,
'string'
,
'Inline CSS styles'
);
$this
->
registerArgument
(
'use'
,
'string'
,
'Inline CSS styles'
);
$this
->
registerArgument
(
'createNewInstance'
,
'boolean'
,
'Creates a new instance without reusing other ones'
);
$this
->
registerArgument
(
'preserveColors'
,
'boolean'
,
'Preserves the original colors'
);
$this
->
registerArgument
(
'createColorAttribute'
,
'boolean'
,
'Creates the color target for cases when it doesn\'t exist.'
,
FALSE
,
FALSE
);
}
}
/**
/**
* Render the SVG file as an inline SVG element.
* Render the SVG file as an inline SVG element.
*
*
* @return string The rendered SVG element
* @return string The rendered SVG element
* @throws
\
Exception
* @throws Exception
*/
*/
public
function
render
():
string
{
public
function
render
():
string
{
global
$tx_sgvideo_svgIds
;
if
(
!
$tx_sgvideo_svgIds
)
{
$tx_sgvideo_svgIds
=
[];
}
$name
=
$this
->
arguments
[
'name'
];
$name
=
$this
->
arguments
[
'name'
];
$path
=
$this
->
arguments
[
'path'
];
$path
=
$this
->
arguments
[
'path'
];
$width
=
$this
->
arguments
[
'width'
];
$width
=
$this
->
arguments
[
'width'
];
$height
=
$this
->
arguments
[
'height'
];
$height
=
$this
->
arguments
[
'height'
];
$viewBox
=
$this
->
arguments
[
'viewBox'
];
$viewBoxOnly
=
$this
->
arguments
[
'viewBoxOnly'
];
$strokeWidth
=
$this
->
arguments
[
'stroke-width'
];
$color
=
$this
->
arguments
[
'color'
];
$color
=
$this
->
arguments
[
'color'
];
$colorAttribute
=
$this
->
arguments
[
'colorAttribute'
];
$id
=
$this
->
arguments
[
'id'
];
$id
=
$this
->
arguments
[
'id'
];
$class
=
$this
->
arguments
[
'class'
];
$class
=
$this
->
arguments
[
'class'
];
$style
=
$this
->
arguments
[
'style'
];
$style
=
$this
->
arguments
[
'style'
];
$title
=
$this
->
arguments
[
'title'
];
$title
=
$this
->
arguments
[
'title'
];
$createNewInstance
=
$this
->
arguments
[
'createNewInstance'
];
$preserveColors
=
$this
->
arguments
[
'preserveColors'
];
$createColorAttribute
=
$this
->
arguments
[
'createColorAttribute'
];
$src
=
$path
??
$this
->
directoryPath
.
'/'
.
$name
.
'.svg'
;
$src
=
$path
??
$this
->
directoryPath
.
'/'
.
$name
.
'.svg'
;
...
@@ -92,7 +143,7 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
...
@@ -92,7 +143,7 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
}
}
// Load the SVG into a SimpleXMLElement object
// Load the SVG into a SimpleXMLElement object
$svg
=
new
\
SimpleXMLElement
(
$content
);
$svg
=
new
SimpleXMLElement
(
$content
);
// Set the attributes of the SVG element
// Set the attributes of the SVG element
if
(
$width
>
0
)
{
if
(
$width
>
0
)
{
...
@@ -103,8 +154,30 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
...
@@ -103,8 +154,30 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
$this
->
addOrReplaceAttribute
(
$svg
,
'height'
,
$height
);
$this
->
addOrReplaceAttribute
(
$svg
,
'height'
,
$height
);
}
}
if
(
!
empty
(
$color
))
{
if
(
!
empty
(
$viewBox
))
{
$this
->
setFill
(
$svg
,
$color
);
$this
->
addOrReplaceAttribute
(
$svg
,
'viewBox'
,
$viewBox
);
}
if
(
$viewBoxOnly
)
{
unset
(
$svg
->
attributes
()
->
width
,
$svg
->
attributes
()
->
height
);
}
if
(
$strokeWidth
>
0
)
{
$this
->
setStrokeWidth
(
$svg
,
$strokeWidth
);
}
if
(
!
empty
(
$color
)
&&
!
$preserveColors
)
{
switch
(
$colorAttribute
)
{
case
'fill'
:
$this
->
setFill
(
$svg
,
$color
,
$createColorAttribute
);
break
;
case
'stroke'
:
$this
->
setStroke
(
$svg
,
$color
,
$createColorAttribute
);
break
;
default
:
$this
->
setFill
(
$svg
,
$color
,
$createColorAttribute
);
$this
->
setStroke
(
$svg
,
$color
,
$createColorAttribute
);
}
}
}
if
(
$style
)
{
if
(
$style
)
{
...
@@ -119,124 +192,106 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
...
@@ -119,124 +192,106 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
$this
->
addOrReplaceAttribute
(
$svg
,
'title'
,
$title
);
$this
->
addOrReplaceAttribute
(
$svg
,
'title'
,
$title
);
}
}
if
(
$createNewInstance
)
{
return
str_replace
(
$this
->
xmlInfo
,
''
,
$svg
->
asXML
());
}
// Extract the SVG contents
// Extract the SVG contents
$contents
=
$this
->
getContents
(
$svg
,
TRUE
);
$contents
=
$this
->
getContents
(
$svg
,
TRUE
);
// Check if the SVG has already been rendered and use the <use> tag if possible
// Check if the SVG has already been rendered and use the <use> tag if possible
if
(
!
empty
(
$tx_sgvideo_svgIds
))
{
if
(
isset
(
static
::
$svgInstances
[
$id
]))
{
if
(
isset
(
$tx_sgvideo_svgIds
[
$id
]))
{
$use
=
$svg
->
addChild
(
'use'
);
$use
=
$svg
->
addChild
(
'use'
);
// The boolean conversion of SimpleXMLElement is broken, therefore we MUST use instanceof
// The boolean conversion of SimpleXMLElement is broken, therefore we MUST use instanceof
if
(
$use
instanceof
SimpleXMLElement
)
{
if
(
$use
instanceof
\SimpleXMLElement
)
{
$use
->
addAttribute
(
'href'
,
'#'
.
$id
);
$use
->
addAttribute
(
'href'
,
'#'
.
$id
);
}
return
$svg
->
asXML
();
}
}
}
else
{
$tx_sgvideo_svgIds
=
[]
;
return
str_replace
(
$this
->
xmlInfo
,
''
,
$svg
->
asXML
())
;
}
}
// Add the unique ID to the list of rendered SVGs
// Add the unique ID to the list of rendered SVGs
$tx_sgvideo_svgId
s
[
$id
]
=
$id
;
static
::
$svgInstance
s
[
$id
]
=
$id
;
$contentsElement
=
new
\
SimpleXMLElement
(
$contents
);
$contentsElement
=
new
SimpleXMLElement
(
$contents
);
$group
=
$svg
->
addChild
(
'g'
);
$group
=
$svg
->
addChild
(
'g'
);
// The boolean conversion of SimpleXMLElement is broken, therefore we MUST explicitly check against null
// The boolean conversion of SimpleXMLElement is broken, therefore we MUST explicitly check against null
if
(
$group
===
NULL
)
{
if
(
$group
===
NULL
)
{
return
$svg
->
asXML
();
return
str_replace
(
$this
->
xmlInfo
,
''
,
$svg
->
asXML
()
)
;
}
}
/** @noinspection NullPointerExceptionInspection */
$group
->
addAttribute
(
'id'
,
$id
);
$group
->
addAttribute
(
'id'
,
$id
);
$this
->
xmlAdopt
(
$group
,
$contentsElement
);
$this
->
xmlAdopt
(
$group
,
$contentsElement
);
return
$svg
->
asXML
();
return
str_replace
(
$this
->
xmlInfo
,
''
,
$svg
->
asXML
());
//Todo: we don't really want this, do we?
// if (!empty($width) && !empty($height)) {
// $resultWithoutCssClass = str_replace($cssClass, '', $result);
// $cssClasses = $this->processWrapperClasses($cssClassPlain);
//
// return "<span $cssClasses style='width: $width; height: $height;'>$resultWithoutCssClass</span>";
// }
//
// if (!empty($width)) {
// $resultWithoutCssClass = str_replace($cssClass, '', $result);
// $cssClasses = $this->processWrapperClasses($cssClassPlain);
//
// return "<span $cssClasses style='width: $width;'>$resultWithoutCssClass</span>";
// }
//
// if (!empty($height)) {
// $resultWithoutCssClass = str_replace($cssClass, '', $result);
// $cssClasses = $this->processWrapperClasses($cssClassPlain);
//
// return "<span $cssClasses style='height: $height;'>$resultWithoutCssClass</span>";
// }
//
// return $result;
}
}
/**
/**
*
Processes the common SVG wrapper's classes
*
Set the fill color of an SVG element.
*
*
* @param string $cssClass
* @param SimpleXMLElement $element The SVG element
* @return string
* @param string $fill The fill color to set
* @param boolean $createColorAttribute If the attribute should be added
*/
*/
public
function
processWrapperClasses
(
string
$cssClass
):
string
{
protected
function
setFill
(
SimpleXMLElement
$element
,
string
$fill
,
bool
$createColorAttribute
):
void
{
return
"class='
$cssClass
svg-wrapper d-inline-flex justify-content-center align-items-center'"
;
foreach
(
$element
->
children
()
as
$child
)
{
$this
->
setFill
(
$child
,
$fill
,
$createColorAttribute
);
}
if
(
$createColorAttribute
)
{
$element
->
addAttribute
(
'fill'
,
$fill
);
}
elseif
(
isset
(
$element
->
attributes
()
->
fill
))
{
$element
->
attributes
()
->
fill
=
$fill
;
}
}
}
/**
/**
*
Processes the wrappers for the usage of the <use> SVG functionality
*
Set the stroke color of an SVG element.
*
*
* @param string $svgContent
* @param SimpleXMLElement $element The SVG element
* @param string $id
* @param string $stroke The stroke color to set
* @param string $use
* @param boolean $createColorAttribute If the attribute should be added
* @return string
*/
*/
public
function
processUseWrappers
(
string
$svgContent
,
string
$id
,
string
$use
):
string
{
protected
function
setStroke
(
SimpleXMLElement
$element
,
string
$stroke
,
bool
$createColorAttribute
):
void
{
$svgContent
=
"<g
$id
>
$svgContent
</g>"
;
foreach
(
$element
->
children
()
as
$child
)
{
$this
->
setStroke
(
$child
,
$stroke
,
$createColorAttribute
);
if
(
$use
)
{
}
$svgContent
=
"<use href='#
$use
' />"
;
if
(
$createColorAttribute
)
{
$element
->
addAttribute
(
'stroke'
,
$stroke
);
}
elseif
(
isset
(
$element
->
attributes
()
->
stroke
))
{
$element
->
attributes
()
->
stroke
=
$stroke
;
}
}
return
$svgContent
;
}
}
/**
/**
* Set the
fill color
of an SVG element.
* Set the
stroke width
of an SVG element.
*
*
* @param
\
SimpleXMLElement $element The SVG element
* @param SimpleXMLElement $element The SVG element
* @param string $
fill The fill color
to set
* @param string $
strokeWidth The stroke width
to set
*/
*/
protected
function
set
Fill
(
\
SimpleXMLElement
$element
,
string
$
fill
)
:
void
{
protected
function
set
StrokeWidth
(
SimpleXMLElement
$element
,
string
$
strokeWidth
):
void
{
foreach
(
$element
->
children
()
as
$child
)
{
foreach
(
$element
->
children
()
as
$child
)
{
$this
->
set
Fill
(
$child
,
$fill
);
$this
->
set
StrokeWidth
(
$child
,
$strokeWidth
);
}
}
if
(
isset
(
$element
->
at
tributes
()
->
fill
)
)
{
foreach
(
$element
->
p
at
h
as
$path
)
{
$
element
->
attributes
()
->
fill
=
$fill
;
$
this
->
addOrReplaceAttribute
(
$path
,
'stroke-width'
,
$strokeWidth
)
;
}
}
}
}
/**
/**
* Gets the contents of the SVG file
* Gets the contents of the SVG file
*
*
* @param
\
SimpleXMLElement $svg
* @param SimpleXMLElement $svg
* @param bool $removeNode
* @param bool $removeNode
* @return string
* @return string
*/
*/
private
function
getContents
(
\
SimpleXMLElement
$svg
,
bool
$removeNode
=
FALSE
)
:
string
{
private
function
getContents
(
SimpleXMLElement
$svg
,
bool
$removeNode
=
FALSE
):
string
{
$contents
=
''
;
$contents
=
''
;
foreach
(
$svg
->
children
()
as
$child
)
{
foreach
(
$svg
->
children
()
as
$child
)
{
$contents
.
=
$child
->
asXML
()
.
"
\n
"
;
$contents
.
=
$child
->
asXML
()
.
"
\n
"
;
if
(
$removeNode
)
{
if
(
$removeNode
)
{
$dom
=
dom_import_simplexml
(
$child
);
$dom
=
dom_import_simplexml
(
$child
);
if
(
$dom
)
{
$dom
->
parentNode
->
removeChild
(
$dom
);
$dom
->
parentNode
->
removeChild
(
$dom
);
}
}
}
}
}
...
@@ -246,20 +301,21 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
...
@@ -246,20 +301,21 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
/**
/**
* Inserts a new SimpleXMLElement at the given root
* Inserts a new SimpleXMLElement at the given root
*
*
* @param
\
SimpleXMLElement $root
* @param SimpleXMLElement $root
* @param
\
SimpleXMLElement $newElement
* @param SimpleXMLElement $newElement
* @return void
* @return void
*/
*/
private
function
xmlAdopt
(
\
SimpleXMLElement
$root
,
\
SimpleXMLElement
$newElement
)
:
void
{
private
function
xmlAdopt
(
SimpleXMLElement
$root
,
SimpleXMLElement
$newElement
):
void
{
$node
=
$root
->
addChild
(
$newElement
->
getName
(),
(
string
)
$newElement
);
$node
=
$root
->
addChild
(
$newElement
->
getName
(),
(
string
)
$newElement
);
if
(
$node
===
NULL
)
{
return
;
}
foreach
(
$newElement
->
attributes
()
as
$attr
=>
$value
)
{
foreach
(
$newElement
->
attributes
()
as
$attr
=>
$value
)
{
/** @noinspection NullPointerExceptionInspection */
$node
->
addAttribute
(
$attr
,
$value
);
$node
->
addAttribute
(
$attr
,
$value
);
}
}
foreach
(
$newElement
->
children
()
as
$ch
)
{
foreach
(
$newElement
->
children
()
as
$ch
)
{
/** @noinspection NullPointerExceptionInspection */
$this
->
xmlAdopt
(
$node
,
$ch
);
$this
->
xmlAdopt
(
$node
,
$ch
);
}
}
}
}
...
@@ -267,20 +323,21 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
...
@@ -267,20 +323,21 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
/**
/**
* Adds or replaces an attribute
* Adds or replaces an attribute
*
*
* @param
\
SimpleXMLElement $element
* @param SimpleXMLElement $element
* @param string $attributeName
* @param string $attributeName
* @param string $attributeValue
* @param string $attributeValue
* @return void
* @return void
*/
*/
private
function
addOrReplaceAttribute
(
private
function
addOrReplaceAttribute
(
\
SimpleXMLElement
$element
,
SimpleXMLElement
$element
,
string
$attributeName
,
string
$attributeName
,
string
$attributeValue
string
$attributeValue
):
void
{
):
void
{
if
(
isset
(
$element
[
$attributeName
]))
{
if
(
isset
(
$element
[
$attributeName
]))
{
$element
->
$attributeName
=
$attributeValue
;
// Replace existing attribute value
// Replace existing attribute value
}
else
{
unset
(
$element
[
$attributeName
]);
$element
->
addAttribute
(
$attributeName
,
$attributeValue
);
// Add new attribute
}
}
$element
->
addAttribute
(
$attributeName
,
$attributeValue
);
}
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment