0&&o');if(this.name=="xaxis"||this.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){var g=this._label.draw(b,j);g.appendTo(this._elem)}var f=this._ticks;for(var e=0;e');g.html(this.groupLabels[e]);this._groupLabels.push(g);g.appendTo(this._elem)}}return this._elem};a.jqplot.CategoryAxisRenderer.prototype.set=function(){var e=0;var m;var k=0;var f=0;var d=(this._label==null)?false:this._label.show;if(this.show){var n=this._ticks;for(var c=0;ce){e=m}}}var j=0;for(var c=0;cj){j=m}}if(d){k=this._label._elem.outerWidth(true);f=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){e+=j+f;this._elem.css({height:e+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){e+=j+f;this._elem.css({height:e+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){e+=j+k;this._elem.css({width:e+"px",left:"0px",top:"0px"});if(d&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",k+"px")}}else{e+=j+k;this._elem.css({width:e+"px",right:"0px",top:"0px"});if(d&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",k+"px")}}}}}};a.jqplot.CategoryAxisRenderer.prototype.pack=function(e,c){var C=this._ticks;var v=this.max;var s=this.min;var n=c.max;var l=c.min;var q=(this._label==null)?false:this._label.show;var x;for(var r in e){this._elem.css(r,e[r])}this._offsets=c;var g=n-l;var k=v-s;if(!this.reverse){this.u2p=function(h){return(h-s)*g/k+l};this.p2u=function(h){return(h-l)*k/g+s};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(h-s)*g/k};this.series_p2u=function(h){return h*k/g+s}}else{this.series_u2p=function(h){return(h-v)*g/k};this.series_p2u=function(h){return h*k/g+v}}}else{this.u2p=function(h){return l+(v-h)*g/k};this.p2u=function(h){return s+(h-l)*k/g};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(v-h)*g/k};this.series_p2u=function(h){return h*k/g+v}}else{this.series_u2p=function(h){return(s-h)*g/k};this.series_p2u=function(h){return h*k/g+s}}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(x=0;x=this._ticks.length-1){continue}if(this._ticks[u]._elem&&this._ticks[u].label!=" "){var o=this._ticks[u]._elem;var r=o.position();B+=r.left+o.outerWidth(true)/2;f++}}B=B/f;this._groupLabels[x].css({left:(B-this._groupLabels[x].outerWidth(true)/2)});this._groupLabels[x].css(z[0],z[1])}}else{for(x=0;x0){b=-o._textRenderer.height*Math.cos(-o._textRenderer.angle)/2}else{b=-o.getHeight()+o._textRenderer.height*Math.cos(o._textRenderer.angle)/2}break;case"middle":b=-o.getHeight()/2;break;default:b=-o.getHeight()/2;break}}else{b=-o.getHeight()/2}var D=this.u2p(o.value)+b+"px";o._elem.css("top",D);o.pack()}}var z=["left",0];if(q){var y=this._label._elem.outerHeight(true);this._label._elem.css("top",n-g/2-y/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px");z=["left",this._label._elem.outerWidth(true)]}else{this._label._elem.css("right","0px");z=["right",this._label._elem.outerWidth(true)]}this._label.pack()}var d=parseInt(this._ticks.length/this.groups,10)+1;for(x=0;x=this._ticks.length-1){continue}if(this._ticks[u]._elem&&this._ticks[u].label!=" "){var o=this._ticks[u]._elem;var r=o.position();B+=r.top+o.outerHeight()/2;f++}}B=B/f;this._groupLabels[x].css({top:B-this._groupLabels[x].outerHeight()/2});this._groupLabels[x].css(z[0],z[1])}}}}})(jQuery);
--------------------------------------------------------------------------------
/Classes/Controller/BackendController.php:
--------------------------------------------------------------------------------
1 | syntaxService = $syntaxService;
39 | }
40 |
41 | /**
42 | * @param ExtensionService $extensionService
43 | * @return void
44 | */
45 | public function injectExtensionService(ExtensionService $extensionService)
46 | {
47 | $this->extensionService = $extensionService;
48 | }
49 |
50 | /**
51 | * @param string $view
52 | * @return void
53 | */
54 | public function indexAction($view = 'Index')
55 | {
56 | $extensions = ExtensionUtility::getAllInstalledFluidEnabledExtensions();
57 | $selectorOptions = ExtensionUtility::getAllInstalledFluidEnabledExtensionsAsSelectorOptions();
58 | $formats = [
59 | 'html' => true,
60 | 'xml' => false,
61 | 'txt' => false,
62 | 'eml' => false,
63 | 'yaml' => false,
64 | 'css' => false,
65 | 'js' => false,
66 | ];
67 | $this->view->assign('csh', BackendUtility::wrapInHelp('builder', 'modules'));
68 | $this->view->assign('view', $view);
69 | $this->view->assign('extensions', $extensions);
70 | $this->view->assign('extensionSelectorOptions', $selectorOptions);
71 | $this->view->assign('formats', $formats);
72 | }
73 |
74 | /**
75 | * @param string $view
76 | * @return void
77 | */
78 | public function buildFormAction($view = 'BuildForm')
79 | {
80 | $author = '';
81 | if (!empty($GLOBALS['BE_USER']->user['realName']) && !empty($GLOBALS['BE_USER']->user['email'])) {
82 | $author = $GLOBALS['BE_USER']->user['realName'] . ' <' . $GLOBALS['BE_USER']->user['email'] . '>';
83 | }
84 | $this->view->assign('csh', BackendUtility::wrapInHelp('builder', 'modules'));
85 | $this->view->assign('view', $view);
86 | $this->view->assign('author', $author);
87 | $isFluidcontentCoreInstalled = ExtensionManagementUtility::isLoaded('fluidcontent_core') ? "'checked'" : null;
88 | $this->view->assign('isFluidcontentCoreInstalled', $isFluidcontentCoreInstalled);
89 | }
90 |
91 | /**
92 | * @param string $name
93 | * @param string $author
94 | * @param string $title
95 | * @param string $description
96 | * @param boolean $controllers
97 | * @param boolean $pages
98 | * @param boolean $content
99 | * @param boolean $vhs
100 | * @param boolean $dry
101 | * @param boolean $verbose
102 | * @return void
103 | */
104 | public function buildAction(
105 | $name,
106 | $author,
107 | $title,
108 | $description,
109 | $controllers,
110 | $pages,
111 | $content,
112 | $vhs,
113 | $dry,
114 | $verbose
115 | ) {
116 | $generator = $this->extensionService->buildProviderExtensionGenerator(
117 | $name,
118 | $author,
119 | $title,
120 | $description,
121 | $controllers,
122 | $pages,
123 | $content,
124 | $vhs
125 | );
126 | $generator->setVerbose($verbose);
127 | $generator->setDry($dry);
128 | if (false === $dry) {
129 | $generator->generate();
130 | }
131 | $this->view->assign('boolean', true);
132 | $this->view->assign('view', 'BuildForm');
133 | $this->view->assign('attributes', $this->arguments->getArrayCopy());
134 | }
135 |
136 | /**
137 | * @param array $syntax
138 | * @param array $extensions
139 | * @param array $formats
140 | * @param array $filteredFiles
141 | */
142 | public function syntaxAction(array $syntax, array $extensions, array $formats, array $filteredFiles = [])
143 | {
144 | if (class_exists(Environment::class)) {
145 | $resourcePath = substr(ExtensionManagementUtility::extPath('builder', 'Resources/Public/'), strlen(Environment::getPublicPath()));
146 | } else {
147 | /** @var DocumentTemplate $document */
148 | $document = &$GLOBALS['TBE_TEMPLATE'];
149 | $resourcePath = $document->backPath . ExtensionManagementUtility::extRelPath('builder') . 'Resources/Public/';
150 | }
151 | $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
152 | $pageRenderer->addJsFile($resourcePath . 'Javascript/jqplot.min.js');
153 | $pageRenderer->addJsFile($resourcePath . 'Javascript/jqplot.canvasTextRenderer.min.js');
154 | $pageRenderer->addJsFile($resourcePath . 'Javascript/jqplot.canvasAxisTickRenderer.min.js');
155 | $pageRenderer->addJsFile($resourcePath . 'Javascript/jqplot.cursor.min.js');
156 | $pageRenderer->addJsFile($resourcePath . 'Javascript/jqplot.categoryAxisRenderer.min.js');
157 | $pageRenderer->addJsFile($resourcePath . 'Javascript/jqplot.barRenderer.min.js');
158 | $pageRenderer->addJsFile($resourcePath . 'Javascript/jqplot.pointLabels.min.js');
159 | $pageRenderer->addJsFile($resourcePath . 'Javascript/plotter.js');
160 | $pageRenderer->addCssFile($resourcePath . 'Stylesheet/analysis.css');
161 | $pageRenderer->addCssFile($resourcePath . 'Stylesheet/jqplot.min.css');
162 | $pageRenderer->addCssFile($resourcePath . 'Stylesheet/plotter.css');
163 | $reports = [];
164 | $csvFormats = trim(implode(',', $formats), ',');
165 | foreach ($extensions as $extensionKey) {
166 | if (true === empty($extensionKey)) {
167 | continue;
168 | }
169 | $extensionFolder = realpath(ExtensionManagementUtility::extPath($extensionKey));
170 | $reports[$extensionKey] = [];
171 | foreach ($syntax as $syntaxName) {
172 | if (true === empty($syntaxName)) {
173 | continue;
174 | }
175 | $reportsForSyntaxName = [];
176 | if ('php' === $syntaxName) {
177 | $reportsForSyntaxName = $this->syntaxService->syntaxCheckPhpFilesInPath(
178 | $extensionFolder . '/Classes'
179 | );
180 | } elseif ('profile' === $syntaxName) {
181 | $files = GlobUtility::getFilesRecursive($extensionFolder, $csvFormats);
182 | if (0 === count($filteredFiles)) {
183 | $filteredFiles = $files;
184 | }
185 | $this->view->assign('files', $files);
186 | $this->view->assign('basePathLength', strlen($extensionFolder));
187 | foreach ($files as $file) {
188 | if (0 < count($filteredFiles) && false === in_array($file, $filteredFiles)) {
189 | continue;
190 | }
191 | /** @var TemplateAnalyzer $templateAnalyzer */
192 | $templateAnalyzer = $this->objectManager->get(TemplateAnalyzer::class);
193 | $shortFilename = substr($file, strpos($file, '/' . $extensionKey . '/') + strlen($extensionKey) + 2);
194 | $reportsForSyntaxName[$shortFilename] = $templateAnalyzer->analyzePathAndFilename($file);
195 | }
196 | $reports[$extensionKey][$syntaxName]['json'] = $this->encodeMetricsToJson($reportsForSyntaxName);
197 | }
198 | $reports[$extensionKey][$syntaxName]['reports'] = $reportsForSyntaxName;
199 | $reports[$extensionKey][$syntaxName]['errors'] = $this->syntaxService->countErrorsInResultCollection(
200 | $reportsForSyntaxName
201 | );
202 | }
203 | }
204 | $this->view->assign('filteredFiles', $filteredFiles);
205 | $this->view->assign('reports', $reports);
206 | $this->view->assign('extensions', $extensions);
207 | $this->view->assign('formats', $formats);
208 | $this->view->assign('syntax', $syntax);
209 | $this->view->assign('view', 'Index');
210 | }
211 |
212 | /**
213 | * @param ParserResult[] $metrics
214 | * @return string
215 | */
216 | protected function encodeMetricsToJson($metrics)
217 | {
218 | foreach ($metrics as $index => $metric) {
219 | $values = $metric->getPayload();
220 | $metrics[$index] = [];
221 | /** @var Metric $value */
222 | foreach ($values as $value) {
223 | $metrics[$index][$value->getName()] = $value->getValue();
224 | }
225 | }
226 | return json_encode($metrics);
227 | }
228 | }
229 |
--------------------------------------------------------------------------------
/Classes/Service/ExtensionService.php:
--------------------------------------------------------------------------------
1 | objectManager = $objectManager;
30 | }
31 |
32 | /**
33 | * @param string $extensionKey Extension key, VendorName.ExtensionName format.
34 | * @param string $author Author, format "Name Lastname "
35 | * @param string $title Title of extension (NULL for auto title)
36 | * @param string $description
37 | * @param boolean $controllers Generate controllers for each FluidTYPO3 feature
38 | * @param boolean $pages Include use of fluidpages
39 | * @param boolean $content Include use of fluidcontent
40 | * @param boolean $backend Include use of fluidbackend
41 | * @param boolean $useVhs Include VHS as dependency
42 | * @param boolean $useFluidcontentCore Include FluidcontentCore as dependency
43 | * @return ExtensionGenerator
44 | */
45 | public function buildProviderExtensionGenerator(
46 | $extensionKey,
47 | $author,
48 | $title = null,
49 | $description = null,
50 | $controllers = false,
51 | $pages = true,
52 | $content = true,
53 | $useVhs = true
54 | ) {
55 | if (!preg_match('/[a-zA-Z]+\\.[a-zA-Z]/', $extensionKey)) {
56 | throw new \InvalidArgumentException('Extension identity must be in VendorName.ExtensionName format', 1601125275);
57 | }
58 | $defaultTitle = 'Provider extension for ' .
59 | (true === $pages ? 'pages ' : '') .
60 | (true === $content ? 'content ' : '');
61 | ;
62 | if (null === $title) {
63 | $title = $defaultTitle;
64 | }
65 | if (null === $description) {
66 | $description = $defaultTitle;
67 | }
68 | $dependencies = [];
69 | if (true === $useVhs) {
70 | array_push($dependencies, 'vhs');
71 | }
72 | $dependenciesArrayString = '';
73 | foreach ($dependencies as $dependency) {
74 | $dependenciesArrayString .= "\n\t\t\t'" . $dependency . "' => '',";
75 | }
76 | list ($nameAndEmail, $companyName) = GeneralUtility::trimExplode(',', $author);
77 | list ($name, $email) = GeneralUtility::trimExplode('<', $nameAndEmail);
78 | $email = trim($email, '>');
79 | $name = addslashes($name);
80 | $companyName = addslashes($companyName);
81 | $description = addslashes($description);
82 | $title = addslashes($title);
83 | $baseVersion = substr(TYPO3_version, 0, strrpos(TYPO3_version, '.'));
84 | $minimumVersion = $baseVersion . '.0';
85 | $maximumVersion = $baseVersion . '.99';
86 | $extensionVariables = [
87 | 'extensionName' => $extensionKey,
88 | 'extensionNamespace' => str_replace('.', '\\', $extensionKey) . '\\',
89 | 'extensionKey' => GeneralUtility::camelCaseToLowerCaseUnderscored(substr($extensionKey, strpos($extensionKey, '.') + 1)),
90 | 'title' => $title,
91 | 'description' => $description,
92 | 'date' => date('d-m-Y H:i'),
93 | 'author' => $name,
94 | 'email' => $email,
95 | 'company' => $companyName,
96 | 'coreMinor' => $minimumVersion,
97 | 'coreMajor' => $maximumVersion,
98 | 'controllers' => $controllers,
99 | 'content' => $content,
100 | 'pages' => $pages,
101 | 'dependencies' => $dependencies,
102 | 'dependenciesCsv' => 0 === count($dependencies) ? '' : ',' . implode(',', $dependencies),
103 | 'dependenciesArray' => $dependenciesArrayString
104 | ];
105 | /** @var ExtensionGenerator $extensionGenerator */
106 | $extensionGenerator = $this->objectManager->get(ExtensionGenerator::class);
107 | $extensionGenerator->setConfiguration($extensionVariables);
108 | return $extensionGenerator;
109 | }
110 |
111 | /**
112 | * Prints information according to the instances properties
113 | *
114 | * @param string $format Desired format. Currently 'text' or 'json'
115 | * @param boolean $detail Detailed Output? Mandatory if $format == 'json'
116 | * @param integer $state Extension state
117 | *
118 | * @return string
119 | */
120 | public function getPrintableInformation($format = 'text', $detail = false, $state = self::STATE_ALL)
121 | {
122 | $extensionInformation = $this->gatherInformation();
123 |
124 | if ('text' === $format) {
125 | $printedInfo = $this->printAsText($extensionInformation, $detail, $state);
126 | return $printedInfo;
127 | } elseif ('json' === $format) {
128 | $printedJsonInfo = $this->printAsJson($extensionInformation);
129 | return $printedJsonInfo;
130 | } else {
131 | return '';
132 | }
133 | }
134 |
135 | /**
136 | * Returns an array of extension information. Which is the same as the --detail switch.
137 | *
138 | * A facade is used as more behaviour might be hidden.
139 | *
140 | * @return array
141 | */
142 | public function getComputableInformation()
143 | {
144 | $extensionInformation = $this->gatherInformation();
145 |
146 | return $extensionInformation;
147 | }
148 |
149 | /**
150 | * Gathers Extension Information
151 | *
152 | * @return array
153 | */
154 | private function gatherInformation()
155 | {
156 | /** @var ListUtility $service */
157 | $service = $this->objectManager->get('TYPO3\CMS\Extensionmanager\Utility\ListUtility');
158 |
159 | $extensionInformation = $service->getAvailableExtensions();
160 | foreach ($extensionInformation as $extensionKey => $info) {
161 | $extensionInformation[$extensionKey]['version'] = ExtensionManagementUtility::getExtensionVersion(
162 | $extensionKey
163 | );
164 | if (ExtensionManagementUtility::isLoaded($extensionKey)) {
165 | $extensionInformation[$extensionKey]['installed'] = 1;
166 | } else {
167 | $extensionInformation[$extensionKey]['installed'] = 0;
168 | }
169 | }
170 | return $extensionInformation;
171 | }
172 |
173 | /**
174 | * Prints text-output
175 | *
176 | * @param array $extensionInformation
177 | * @param boolean $detail
178 | * @param int $state
179 | *
180 | * @return string
181 | */
182 | private function printAsText($extensionInformation, $detail = false, $state = self::STATE_ALL)
183 | {
184 | $output = '';
185 | foreach ($extensionInformation as $extension => $info) {
186 | if (false === $detail) {
187 | switch ($state) {
188 | case self::STATE_INACTIVE:
189 | if (0 === intval($info['installed'])) {
190 | $output .= $extension . LF;
191 | }
192 | break;
193 | case self::STATE_ACTIVE:
194 | if (1 === intval($info['installed'])) {
195 | $output .= $extension . LF;
196 | }
197 | break;
198 | default:
199 | $output .= $extension . LF;
200 | break;
201 | }
202 | } elseif (true === $detail) {
203 | switch ($state) {
204 | case self::STATE_INACTIVE:
205 | if (0 === intval($info['installed'])) {
206 | $output .= $this->concatStringOutput($extension, $info);
207 | }
208 | break;
209 | case self::STATE_ACTIVE:
210 | if (1 === intval($info['installed'])) {
211 | $output .= $this->concatStringOutput($extension, $info);
212 | }
213 | break;
214 | default:
215 | $output .= $this->concatStringOutput($extension, $info);
216 | break;
217 | }
218 | }
219 | }
220 | return $output;
221 | }
222 |
223 | /**
224 | * Concats the detailed output to yaml
225 | *
226 | * @param string $extension Extension Name
227 | * @param array $info Extension Information
228 | * @return string
229 | */
230 | private function concatStringOutput($extension, $info)
231 | {
232 | return $extension . ':' . LF .
233 | ' version: ' . $info['version'] . LF .
234 | ' installed: ' . $info['installed'] . LF .
235 | ' type: ' . $info['type'] . LF .
236 | ' path: ' . $info['siteRelPath'] .
237 | LF;
238 | }
239 |
240 | /**
241 | * @param array $extensionInformation
242 | *
243 | * @return string
244 | */
245 | public function printAsJson($extensionInformation)
246 | {
247 | $json = json_encode($extensionInformation) . LF;
248 |
249 | return $json;
250 | }
251 | }
252 |
--------------------------------------------------------------------------------
/Resources/Public/Javascript/jqplot.barRenderer.min.js:
--------------------------------------------------------------------------------
1 | /* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com
2 | jsDate | (c) 2010-2013 Chris Leonello
3 | */(function(d){d.jqplot.BarRenderer=function(){d.jqplot.LineRenderer.call(this)};d.jqplot.BarRenderer.prototype=new d.jqplot.LineRenderer();d.jqplot.BarRenderer.prototype.constructor=d.jqplot.BarRenderer;d.jqplot.BarRenderer.prototype.init=function(o,q){this.barPadding=8;this.barMargin=10;this.barDirection="vertical";this.barWidth=null;this.shadowOffset=2;this.shadowDepth=5;this.shadowAlpha=0.08;this.waterfall=false;this.groups=1;this.varyBarColor=false;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.transposedData=true;this.renderer.animation={show:false,direction:"down",speed:3000,_supported:true};this._type="bar";if(o.highlightMouseDown&&o.highlightMouseOver==null){o.highlightMouseOver=false}d.extend(true,this,o);d.extend(true,this.renderer,o);this.fill=true;if(this.barDirection==="horizontal"&&this.rendererOptions.animation&&this.rendererOptions.animation.direction==null){this.renderer.animation.direction="left"}if(this.waterfall){this.fillToZero=false;this.disableStack=true}if(this.barDirection=="vertical"){this._primaryAxis="_xaxis";this._stackAxis="y";this.fillAxis="y"}else{this._primaryAxis="_yaxis";this._stackAxis="x";this.fillAxis="x"}this._highlightedPoint=null;this._plotSeriesInfo=null;this._dataColors=[];this._barPoints=[];var p={lineJoin:"miter",lineCap:"round",fill:true,isarc:false,strokeStyle:this.color,fillStyle:this.color,closePath:this.fill};this.renderer.shapeRenderer.init(p);var n={lineJoin:"miter",lineCap:"round",fill:true,isarc:false,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,closePath:this.fill};this.renderer.shadowRenderer.init(n);q.postInitHooks.addOnce(h);q.postDrawHooks.addOnce(j);q.eventListenerHooks.addOnce("jqplotMouseMove",b);q.eventListenerHooks.addOnce("jqplotMouseDown",a);q.eventListenerHooks.addOnce("jqplotMouseUp",l);q.eventListenerHooks.addOnce("jqplotClick",e);q.eventListenerHooks.addOnce("jqplotRightClick",m)};function g(t,p,o,w){if(this.rendererOptions.barDirection=="horizontal"){this._stackAxis="x";this._primaryAxis="_yaxis"}if(this.rendererOptions.waterfall==true){this._data=d.extend(true,[],this.data);var s=0;var u=(!this.rendererOptions.barDirection||this.rendererOptions.barDirection==="vertical"||this.transposedData===false)?1:0;for(var q=0;q0){this.data[q][u]+=this.data[q-1][u]}}this.data[this.data.length]=(u==1)?[this.data.length+1,s]:[s,this.data.length+1];this._data[this._data.length]=(u==1)?[this._data.length+1,s]:[s,this._data.length+1]}if(this.rendererOptions.groups>1){this.breakOnNull=true;var n=this.data.length;var v=parseInt(n/this.rendererOptions.groups,10);var r=0;for(var q=v;q570)?n[p]*0.8:n[p]+0.3*(255-n[p]);n[p]=parseInt(n[p],10)}q.push("rgb("+n[0]+","+n[1]+","+n[2]+")")}return q}function i(v,u,s,t,o){var q=v,w=v-1,n,p,r=(o==="x")?0:1;if(q>0){p=t.series[w]._plotData[u][r];if((s*p)<0){n=i(w,u,s,t,o)}else{n=t.series[w].gridData[u][r]}}else{n=(r===0)?t.series[q]._xaxis.series_u2p(0):t.series[q]._yaxis.series_u2p(0)}return n}d.jqplot.BarRenderer.prototype.draw=function(E,L,q,G){var I;var A=d.extend({},q);var w=(A.shadow!=undefined)?A.shadow:this.shadow;var O=(A.showLine!=undefined)?A.showLine:this.showLine;var F=(A.fill!=undefined)?A.fill:this.fill;var p=this.xaxis;var J=this.yaxis;var y=this._xaxis.series_u2p;var K=this._yaxis.series_u2p;var D,C;this._dataColors=[];this._barPoints=[];if(this.barWidth==null){this.renderer.setBarWidth.call(this)}var N=this._plotSeriesInfo=this.renderer.calcSeriesNumbers.call(this);var x=N[0];var v=N[1];var s=N[2];var H=[];if(this._stack){this._barNudge=0}else{this._barNudge=(-Math.abs(v/2-0.5)+s)*(this.barWidth+this.barPadding)}if(O){var u=new d.jqplot.ColorGenerator(this.negativeSeriesColors);var B=new d.jqplot.ColorGenerator(this.seriesColors);var M=u.get(this.index);if(!this.useNegativeColors){M=A.fillStyle}var t=A.fillStyle;var r;var P;var o;if(this.barDirection=="vertical"){for(var I=0;I0&&I=0){o=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){o=E.canvas.height}else{o=0}}}else{if(this.waterfall&&I==this.gridData.length-1){if(this._yaxis.min<=0&&this._yaxis.max>=0){o=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){o=E.canvas.height}else{o=0}}}else{o=E.canvas.height}}}}}if((this.fillToZero&&this._plotData[I][1]<0)||(this.waterfall&&this._data[I][1]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){A.fillStyle=u.next()}else{A.fillStyle=B.next()}}else{A.fillStyle=M}}else{if(this.varyBarColor&&!this._stack){A.fillStyle=B.next()}else{A.fillStyle=t}}if(!this.fillToZero||this._plotData[I][1]>=0){H.push([r-this.barWidth/2,o]);H.push([r-this.barWidth/2,L[I][1]]);H.push([r+this.barWidth/2,L[I][1]]);H.push([r+this.barWidth/2,o])}else{H.push([r-this.barWidth/2,L[I][1]]);H.push([r-this.barWidth/2,o]);H.push([r+this.barWidth/2,o]);H.push([r+this.barWidth/2,L[I][1]])}this._barPoints.push(H);if(w&&!this._stack){var z=d.extend(true,{},A);delete z.fillStyle;this.renderer.shadowRenderer.draw(E,H,z)}var n=A.fillStyle||this.color;this._dataColors.push(n);this.renderer.shapeRenderer.draw(E,H,A)}}else{if(this.barDirection=="horizontal"){for(var I=0;I0&&I=0){P=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){P=0}else{P=0}}}else{if(this.waterfall&&I==this.gridData.length-1){if(this._xaxis.min<=0&&this._xaxis.max>=0){P=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){P=0}else{P=E.canvas.width}}}else{P=0}}}}}if((this.fillToZero&&this._plotData[I][0]<0)||(this.waterfall&&this._data[I][0]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){A.fillStyle=u.next()}else{A.fillStyle=B.next()}}else{A.fillStyle=M}}else{if(this.varyBarColor&&!this._stack){A.fillStyle=B.next()}else{A.fillStyle=t}}if(!this.fillToZero||this._plotData[I][0]>=0){H.push([P,r+this.barWidth/2]);H.push([P,r-this.barWidth/2]);H.push([L[I][0],r-this.barWidth/2]);H.push([L[I][0],r+this.barWidth/2])}else{H.push([L[I][0],r+this.barWidth/2]);H.push([L[I][0],r-this.barWidth/2]);H.push([P,r-this.barWidth/2]);H.push([P,r+this.barWidth/2])}this._barPoints.push(H);if(w&&!this._stack){var z=d.extend(true,{},A);delete z.fillStyle;this.renderer.shadowRenderer.draw(E,H,z)}var n=A.fillStyle||this.color;this._dataColors.push(n);this.renderer.shapeRenderer.draw(E,H,A)}}}}if(this.highlightColors.length==0){this.highlightColors=d.jqplot.computeHighlightColors(this._dataColors)}else{if(typeof(this.highlightColors)=="string"){var N=this.highlightColors;this.highlightColors=[];for(var I=0;IsyntaxService = $syntaxService ?? GeneralUtility::makeInstance(ObjectManager::class)->get(SyntaxService::class);
38 | $this->extensionService = $extensionService ?? GeneralUtility::makeInstance(ObjectManager::class)->get(ExtensionService::class);
39 | }
40 |
41 | /**
42 | * @param Response $response
43 | */
44 | public function setResponse(Response $response): void
45 | {
46 | $this->response = $response;
47 | }
48 |
49 | /**
50 | * @param OutputInterface $output
51 | */
52 | public function setOutput(OutputInterface $output): void
53 | {
54 | $this->output = $output;
55 | }
56 |
57 | /**
58 | * Lists installed Extensions. The output defaults to text and is new-line separated.
59 | *
60 | * @param boolean $detail If TRUE, the command will give detailed information such as version and state
61 | * @param boolean $active If TRUE, the command will give information about active extensions only
62 | * @param boolean $inactive If TRUE, the command will give information about inactive extensions only
63 | * @param boolean $json If TRUE, the command will return a json object-string
64 | * @throws \Exception
65 | * @return int
66 | */
67 | public function listExtensions(bool $detail = false, bool $active = true, bool $inactive = false, bool $json = false): int
68 | {
69 | $format = 'text';
70 | if (true === $json) {
71 | $format = 'json';
72 | }
73 | if ($active && $inactive) {
74 | $state = ExtensionService::STATE_ALL;
75 | } elseif ($active && !$inactive) {
76 | $state = ExtensionService::STATE_ACTIVE;
77 | } elseif ($inactive && !$active) {
78 | $state = ExtensionService::STATE_INACTIVE;
79 | } else {
80 | $state = ExtensionService::STATE_ALL;
81 | }
82 |
83 | $this->setContent(
84 | $this->extensionService->getPrintableInformation($format, $detail, $state)
85 | );
86 |
87 | return 0;
88 | }
89 |
90 | /**
91 | * Syntax check Fluid template
92 | *
93 | * Checks one template file, all templates in
94 | * an extension or a sub-path (which can be used
95 | * with an extension key for a relative path).
96 | * If left out, it will lint ALL templates in
97 | * EVERY local extension.
98 | *
99 | * @param string $extension Optional extension key (if path is set too it will apply to sub-folders in extension)
100 | * @param string $path file or folder path (if extensionKey is included, path is relative to this extension)
101 | * @param string $extensions If provided, this CSV list of file extensions are considered Fluid templates
102 | * @param boolean $verbose If TRUE outputs more information about each file check - default is to only output errors
103 | * @throws \RuntimeException
104 | * @return int
105 | */
106 | public function checkFluidSyntax(?String $extension = null, ?string $path = null, string $extensions = 'html,xml,txt', bool $verbose = false): int
107 | {
108 | if (null !== $extension) {
109 | $this->assertEitherExtensionKeyOrPathOrBothAreProvidedOrExit($extension, $path);
110 | $path = GlobUtility::getRealPathFromExtensionKeyAndPath($extension, $path);
111 | $files = GlobUtility::getFilesRecursive($path, $extensions);
112 | } else {
113 | // no extension key given, let's lint it all
114 | $files = [];
115 | /** @var ExtensionService $extensionService */
116 | $extensionInformation = $this->extensionService->getComputableInformation();
117 | foreach ($extensionInformation as $extensionName => $extensionInfo) {
118 | // Syntax service declines linting of inactive extensions
119 | if (0 === intval($extensionInfo['installed']) || 'System' === $extensionInfo['type']) {
120 | continue;
121 | }
122 | $path = GlobUtility::getRealPathFromExtensionKeyAndPath($extensionName, null);
123 | $files = array_merge($files, GlobUtility::getFilesRecursive($path, $extensions));
124 | }
125 | }
126 | $files = array_values($files);
127 | $errors = false;
128 | $this->setContent(
129 | 'Performing a syntax check on fluid templates (types: ' . $extensions . '; path: ' . $path . ')' . LF
130 | );
131 | $this->send();
132 | foreach ($files as $filePathAndFilename) {
133 | $basePath = str_replace(Environment::getProjectPath(), '', $filePathAndFilename);
134 | $result = $this->syntaxService->syntaxCheckFluidTemplateFile($filePathAndFilename);
135 | if (null !== $result->getError()) {
136 | $this->appendContent('[ERROR] File ' . $basePath . ' has an error: ' . LF);
137 | $this->appendContent(
138 | $result->getError()->getMessage() . ' (' . $result->getError()->getCode() . ')' . LF
139 | );
140 | $this->send();
141 | $errors = true;
142 | } elseif (true === $verbose) {
143 | $namespaces = $result->getNamespaces();
144 | $this->appendContent(
145 | 'File is compilable: ' . ($result->getCompilable() ? 'YES' : 'NO (WARNING)') . LF
146 | );
147 | if ($result->getLayoutName()) {
148 | $this->appendContent('File has layout (' . $result->getLayoutName() . ')' . LF);
149 | } else {
150 | $this->appendContent('File DOES NOT reference a Layout' . LF);
151 | }
152 | $this->appendContent(
153 | 'File has ' . count($namespaces) . ' namespace(s)' .
154 | (0 < count($namespaces) ? ': ' . $result->getNamespacesFlattened() : '') . LF
155 | );
156 | }
157 | if (null === $result->getError()) {
158 | $this->appendContent('[OK] File ' . $basePath . ' is valid.' . LF);
159 | $this->send();
160 | }
161 | }
162 | return $this->stop($files, $errors, $verbose);
163 | }
164 |
165 | /**
166 | * Syntax check PHP code
167 | *
168 | * Checks PHP source files in $path, if extension
169 | * key is also given, only files in that path relative
170 | * to that extension are checked.
171 | *
172 | * @param string $extension Optional extension key (if path is set too it will apply to sub-folders in extension)
173 | * @param string $path file or folder path (if extensionKey is included, path is relative to this extension)
174 | * @param boolean $verbose If TRUE outputs more information about each file check - default is to only output errors
175 | * @return int
176 | */
177 | public function checkPhpSyntax(?string $extension = null, ?string $path = null, bool $verbose = false): int
178 | {
179 | $verbose = (boolean) $verbose;
180 | $this->assertEitherExtensionKeyOrPathOrBothAreProvidedOrExit($extension, $path);
181 | if (null !== $extension) {
182 | $results = $this->syntaxService->syntaxCheckPhpFilesInExtension($extension);
183 | } else {
184 | $results = $this->syntaxService->syntaxCheckPhpFilesInPath($path);
185 | }
186 | $errors = false;
187 | foreach ($results as $filePathAndFilename => $result) {
188 | $result = $this->syntaxService->syntaxCheckPhpFile($filePathAndFilename);
189 | if (null !== $result->getError()) {
190 | $errors = true;
191 | $this->setContent(
192 | '[ERROR] ' . $result->getError()->getMessage() . ' (' . $result->getError()->getCode() . ')' . LF
193 | );
194 | }
195 | }
196 | return $this->stop($results, $errors, $verbose);
197 | }
198 |
199 | /**
200 | * Builds a ProviderExtension
201 | *
202 | * The resulting extension will contain source code
203 | * and configuration options needed by the various
204 | * toggles. Each of these toggles enable/disable
205 | * generation of source code and configuration for
206 | * that particular feature.
207 | *
208 | * @param string $extensionKey The extension key which should be generated. Must not exist.
209 | * @param string $author The author of the extension, in the format "Name Lastname " with optional
210 | * company name, in which case form is "Name Lastname , Company Name"
211 | * @param string $title Title of the resulting extension, by default "Provider extension for $enabledFeaturesList"
212 | * @param string $description Description for extension, by default "Provider extension for $enabledFeaturesList"
213 | * @param boolean $useVhs If TRUE, adds the VHS extension as dependency - recommended, on by default
214 | * @param boolean $pages If TRUE, generates basic files for implementing Fluid Page templates
215 | * @param boolean $content IF TRUE, generates basic files for implementing Fluid Content templates
216 | * @param boolean $controllers If TRUE, generates controllers for each enabled feature. Enabling $backend will
217 | * always generate a controller regardless of this toggle.
218 | * @param boolean $dry If TRUE performs a dry run without writing files;reports which files would have been written
219 | * @param boolean $verbose If FALSE, suppresses a lot of the otherwise output messages (to STDOUT)
220 | * @return int
221 | */
222 | public function generateProviderExtension(
223 | string $extensionKey,
224 | string $author,
225 | ?string $title = null,
226 | ?string $description = null,
227 | bool $useVhs = true,
228 | bool $pages = true,
229 | bool $content = true,
230 | bool $controllers = true,
231 | bool $dry = false,
232 | bool $verbose = true
233 | ):int {
234 | $extensionGenerator = $this->extensionService->buildProviderExtensionGenerator(
235 | $extensionKey,
236 | $author,
237 | $title,
238 | $description,
239 | $controllers,
240 | $pages,
241 | $content,
242 | $useVhs
243 | );
244 | $extensionGenerator->setDry($dry);
245 | $extensionGenerator->setVerbose($verbose);
246 | $this->setContent($extensionGenerator->generate() . PHP_EOL);
247 | return 0;
248 | }
249 |
250 | private function assertEitherExtensionKeyOrPathOrBothAreProvidedOrExit(?string $extension, ?string $path): void
251 | {
252 | if (null === $extension && null === $path) {
253 | $this->setContent('Either "extension" or "path" or both must be specified' . LF);
254 | $this->send();
255 | $this->setExitCode(128);
256 | }
257 | }
258 |
259 | private function send(): void
260 | {
261 | if ($this->response instanceof ResponseInterface) {
262 | $this->response->send();
263 | }
264 | }
265 |
266 | private function setContent(string $content): void
267 | {
268 | if ($this->output instanceof OutputInterface) {
269 | $this->output->write($content);
270 | } elseif ($this->response instanceof ResponseInterface) {
271 | $this->response->setContent($content);
272 | }
273 | }
274 |
275 | private function appendContent(string $content): void
276 | {
277 | if ($this->output instanceof OutputInterface) {
278 | $this->output->write($content);
279 | } elseif ($this->response instanceof ResponseInterface) {
280 | $this->response->appendContent($content);
281 | }
282 | }
283 |
284 | private function setExitCode(int $code): void
285 | {
286 | if ($this->response instanceof ResponseInterface) {
287 | $this->response->setExitCode($code);
288 | }
289 | }
290 |
291 | private function stop(array $files, bool $errors, bool $verbose): int
292 | {
293 | $code = (int) $errors;
294 | if (true === (boolean) $verbose) {
295 | if (false === $errors) {
296 | $this->setContent('No errors encountered - ' . count($files) . ' file(s) are all okay' . LF);
297 | } else {
298 | $this->setContent('Errors were detected - review the summary above' . LF);
299 | $this->setExitCode($code);
300 | }
301 | }
302 | $this->send();
303 | return $code;
304 | }
305 | }
306 |
--------------------------------------------------------------------------------
/Classes/CodeGeneration/Extension/ExtensionGenerator.php:
--------------------------------------------------------------------------------
1 | configuration = $configuration;
42 | }
43 |
44 | /**
45 | * @param string $targetFolder
46 | * @return void
47 | */
48 | public function setTargetFolder($targetFolder)
49 | {
50 | $this->targetFolder = $targetFolder;
51 | }
52 |
53 | /**
54 | * @return string
55 | */
56 | protected function getExtensionKeyFromSettings()
57 | {
58 | $extensionKey = $this->configuration['extensionKey'];
59 | if (false !== strpos($extensionKey, '.')) {
60 | $extensionKey = array_pop(explode('.', $extensionKey));
61 | }
62 | return GeneralUtility::camelCaseToLowerCaseUnderscored($extensionKey);
63 | }
64 |
65 | /**
66 | * @return string
67 | */
68 | protected function getExtensionNamespaceFromSettings()
69 | {
70 | return $this->configuration['extensionNamespace'];
71 | }
72 |
73 | /**
74 | * @return string
75 | * @throws \RuntimeException
76 | */
77 | public function generate()
78 | {
79 | $extensionKey = $this->getExtensionKeyFromSettings();
80 | if (null === $this->targetFolder) {
81 | $this->setTargetFolder((defined('PATH_site') ? constant('PATH_typo3conf') . 'ext/' : Environment::getPublicPath() . '/typo3conf/ext/') . $extensionKey);
82 | }
83 | if (true === is_dir($this->targetFolder)) {
84 | throw new \RuntimeException(
85 | 'Extension key "' . $extensionKey . '" already has a folder in "' . $this->targetFolder . '"',
86 | 1371692599
87 | );
88 | }
89 | $filesToBeWritten = [
90 | $this->targetFolder . '/ext_emconf.php' => $this->getPreparedCodeTemplate(
91 | self::TEMPLATE_EMCONF,
92 | $this->configuration
93 | )->render()
94 | ];
95 | $foldersToBeCreated = [$this->targetFolder];
96 | $hasVhs = true === in_array('vhs', $this->configuration['dependencies']);
97 | $appendLanguageFile = false;
98 | if ($this->configuration['pages'] ?? false) {
99 | $this->appendPageFiles($filesToBeWritten);
100 | $appendLanguageFile = true;
101 | }
102 | if ($this->configuration['content'] ?? false) {
103 | $this->appendContentFiles($filesToBeWritten, $hasVhs);
104 | $appendLanguageFile = true;
105 | }
106 | if ($appendLanguageFile) {
107 | $this->appendLanguageFile($filesToBeWritten);
108 | }
109 | $controllerFolder = $this->targetFolder . '/Classes/Controller/';
110 | if (true === $this->configuration['controllers']) {
111 | array_push($foldersToBeCreated, $controllerFolder);
112 | }
113 | if (true === $this->configuration['controllers']) {
114 | if ($this->configuration['content'] ?? false) {
115 | $this->appendControllerClassFile(
116 | $filesToBeWritten,
117 | 'Content',
118 | ContentController::class,
119 | $controllerFolder
120 | );
121 | }
122 | if ($this->configuration['pages'] ?? false) {
123 | $this->appendControllerClassFile(
124 | $filesToBeWritten,
125 | 'Page',
126 | PageController::class,
127 | $controllerFolder
128 | );
129 | }
130 | }
131 | $this->appendTypoScriptConfiguration($filesToBeWritten);
132 | $this->appendExtensionLocalconfFile($filesToBeWritten);
133 | $this->appendTypoScriptIntegrationFile($filesToBeWritten);
134 | $foldersToBeCreated = array_unique($foldersToBeCreated);
135 | foreach ($foldersToBeCreated as $folderPathToBeCreated) {
136 | $this->createFolder($folderPathToBeCreated);
137 | }
138 | foreach ($filesToBeWritten as $fileToBeWritten => $fileContentToBeWritten) {
139 | $this->createFile($fileToBeWritten, $fileContentToBeWritten);
140 | }
141 | if ($this->configuration['pages'] ?? false) {
142 | $this->copyFile(
143 | 'Resources/Public/Icons/Example.svg',
144 | $this->targetFolder . '/Resources/Public/Icons/Page/Standard.svg'
145 | );
146 | }
147 | if ($this->configuration['content'] ?? false) {
148 | $this->copyFile(
149 | 'Resources/Public/Icons/Example.svg',
150 | $this->targetFolder . '/Resources/Public/Icons/Content/Example.svg'
151 | );
152 | }
153 | $this->copyFile(
154 | 'Resources/Public/Icons/Example.svg',
155 | $this->targetFolder . '/Resources/Public/Icons/Extension.svg'
156 | );
157 | return 'Built extension "' . $extensionKey . '"';
158 | }
159 |
160 | /**
161 | * @param array $files
162 | * @param string $controllerName
163 | * @param string $parentControllerClassName
164 | * @param string $folder
165 | */
166 | protected function appendControllerClassFile(&$files, $controllerName, $parentControllerClassName, $folder)
167 | {
168 | $templateVariables = $this->configuration;
169 | $templateVariables['controllerName'] = $controllerName;
170 | $templateVariables['parentControllerClass'] = $parentControllerClassName;
171 | $templateVariables['namespace'] = $this->getExtensionNamespaceFromSettings() . 'Controller';
172 | $files[$folder . $controllerName . 'Controller.php'] = $this->getPreparedCodeTemplate(
173 | self::TEMPLATE_CONTROLLER,
174 | $templateVariables
175 | )->render();
176 | }
177 |
178 | /**
179 | * @param array $files
180 | * @return void
181 | */
182 | protected function appendTypoScriptConfiguration(&$files)
183 | {
184 | $extensionKey = $this->getExtensionKeyFromSettings();
185 | $templateVariables = [
186 | 'extension' => $extensionKey,
187 | 'signature' => ExtensionManagementUtility::getCN($extensionKey)
188 | ];
189 | $folder = $this->targetFolder . '/Configuration/TypoScript';
190 | $files[$folder . '/constants.typoscript'] = $this->getPreparedCodeTemplate(
191 | self::TEMPLATE_TYPOSCRIPTCONSTANTS,
192 | $templateVariables
193 | )->render();
194 | $files[$folder . '/setup.typoscript'] = $this->getPreparedCodeTemplate(
195 | self::TEMPLATE_TYPOSCRIPTSETUP,
196 | $templateVariables
197 | )->render();
198 | }
199 |
200 | /**
201 | * @param array $files
202 | * @return void
203 | */
204 | protected function appendExtensionLocalconfFile(&$files)
205 | {
206 | $templateVariables = [
207 | 'pages' => '',
208 | 'content' => '',
209 | 'configuration' => '',
210 | ];
211 |
212 | // note: the following code uses the provided "extensionKey" *directly* because
213 | // for these registrations, we require the full Vendor.ExtensionName if that
214 | // is the format used. Otherwise, legacy class names would be expected.
215 | if ($this->configuration['pages'] ?? false) {
216 | $templateVariables['pages'] = '\FluidTYPO3\Flux\Core::registerProviderExtensionKey(\'' .
217 | $this->configuration['extensionName'] . '\', \'Page\');';
218 | }
219 | if ($this->configuration['content'] ?? false) {
220 | $templateVariables['content'] = '\FluidTYPO3\Flux\Core::registerProviderExtensionKey(\'' .
221 | $this->configuration['extensionName'] . '\', \'Content\');';
222 | }
223 | $files[$this->targetFolder . '/ext_localconf.php'] = $this->getPreparedCodeTemplate(
224 | self::TEMPLATE_EXTLOCALCONF,
225 | $templateVariables
226 | )->render();
227 | }
228 |
229 | /**
230 | * @param array $files
231 | * @return void
232 | */
233 | protected function appendTypoScriptIntegrationFile(&$files)
234 | {
235 | $title = trim($this->configuration['title']);
236 | $templateVariables = [
237 | 'pages' => '',
238 | 'content' => '',
239 | 'configuration' => sprintf(
240 | '\\%s::addStaticFile(\'%s\', \'Configuration/TypoScript\', \'%s\');',
241 | ExtensionManagementUtility::class,
242 | $this->configuration['extensionKey'],
243 | $title
244 | )
245 | ];
246 |
247 | $files[$this->targetFolder . '/Configuration/TCA/Overrides/sys_template.php'] = $this->getPreparedCodeTemplate(
248 | self::TEMPLATE_EXTLOCALCONF,
249 | $templateVariables
250 | )->render();
251 | }
252 |
253 | /**
254 | * @param array $files
255 | * @return void
256 | */
257 | protected function appendLanguageFile(&$files)
258 | {
259 | $variables = [
260 | 'extension' => $this->getExtensionKeyFromSettings(),
261 | 'date' => date('c')
262 | ];
263 | $filePathAndFilename = $this->targetFolder . '/Resources/Private/Language/locallang.xlf';
264 | $files[$filePathAndFilename] = $this->getPreparedCodeTemplate(
265 | self::TEMPLATE_LANGUAGEFILE,
266 | $variables
267 | )->render();
268 | }
269 |
270 | /**
271 | * @param array $files
272 | * @param boolean $hasVhs
273 | * @return void
274 | */
275 | protected function appendContentFiles(&$files, $hasVhs)
276 | {
277 | $layoutName = 'Content';
278 | $sectionName = 'Main';
279 | $variables = [
280 | 'formId' => 'example'
281 | ];
282 | $this->appendLayoutFile($files, $layoutName);
283 | if (true === $hasVhs) {
284 | $variables['vhs'] = 'xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"';
285 | $layoutName = 'Content';
286 | }
287 | $this->appendTemplateFile(
288 | $files,
289 | self::TEMPLATE_CONTENT,
290 | $layoutName,
291 | $sectionName,
292 | 'Content/Example.html',
293 | $variables
294 | );
295 | }
296 |
297 | /**
298 | * @param array $files
299 | * @return void
300 | */
301 | protected function appendPageFiles(&$files)
302 | {
303 | $layoutName = 'Page';
304 | $sectionName = 'Main';
305 | $variables = [
306 | 'formId' => 'standard'
307 | ];
308 | $this->appendLayoutFile($files, $layoutName);
309 | $this->appendTemplateFile(
310 | $files,
311 | self::TEMPLATE_PAGE,
312 | $layoutName,
313 | $sectionName,
314 | 'Page/Standard.html',
315 | $variables
316 | );
317 | }
318 |
319 | /**
320 | * @param array $files
321 | * @param string $identifier
322 | * @param string $layout
323 | * @param string $section
324 | * @param string $placement
325 | * @param array $variables
326 | * @return void
327 | */
328 | protected function appendTemplateFile(&$files, $identifier, $layout, $section, $placement, array $variables)
329 | {
330 | $templateVariables = [
331 | 'layout' => $layout,
332 | 'section' => $section,
333 | 'configurationSectionName' => 'Configuration',
334 | 'id' => str_replace('/', '', strtolower($identifier)),
335 | 'label' => $identifier,
336 | 'icon' => 'Icons/' . substr($placement, 0, -4) . 'gif',
337 | 'extension' => $this->getExtensionKeyFromSettings(),
338 | 'placement' => $placement
339 | ];
340 | $templateVariables = array_merge_recursive($variables, $templateVariables);
341 | $templatePathAndFilename = $this->targetFolder . '/Resources/Private/Templates/' . $placement;
342 | $files[$templatePathAndFilename] = $this->getPreparedCodeTemplate($identifier, $templateVariables)->render();
343 | }
344 |
345 | /**
346 | * @param array $files
347 | * @param string $layoutName
348 | * @param string $layoutSectionRenderName
349 | * @param string $layoutType
350 | */
351 | protected function appendLayoutFile(
352 | &$files,
353 | $layoutName,
354 | $layoutSectionRenderName = 'Main',
355 | $layoutType = self::TEMPLATE_LAYOUT
356 | ) {
357 | $layoutVariables = [
358 | 'name' => $layoutName,
359 | 'section' => $layoutSectionRenderName
360 | ];
361 | $layoutPathAndFilename = $this->targetFolder . '/Resources/Private/Layouts/' . $layoutName . '.html';
362 | $files[$layoutPathAndFilename] = $this->getPreparedCodeTemplate($layoutType, $layoutVariables)->render();
363 | }
364 | }
365 |
--------------------------------------------------------------------------------