Resize image in custom ViewHelper - typo3

I have a ViewHelper that processes some images. I have an image path to an original file. I need to resize this image.
Is there a PHP code I can use in TYPO3 to do this?
I tried this:
$imgPath = 'img/path/from_database.jpg
$imgConf = array();
$imgConf['file'] = $imgPath;
$imgConf['altText'] = "Sample alt text.";
$image = $this->cObj->IMAGE($imgConf);
but I'm getting this exception: "Call to a member function IMAGE() on null"
My ViewHelper inherits from: \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper

First of all you should say what TYPO3 version you use and if your extension uses Extbase or the old pibased code.
I guess it's Extbase since you inherit from a namespaced viewhelper. My advice would be to take a look at the original f:image viewhelper code (TYPO3\CMS\Fluid\ViewHelpers\ImageViewHelper) and copy what you need.
first add this to the top part of you viewhelper:
/**
* #var \TYPO3\CMS\Extbase\Service\ImageService
* #inject
*/
protected $imageService;
Then the code in your method
$image = $this->imageService->getImage($imgPath);
// you have to set these variables or remove if you don't need them
$processingInstructions = array(
'width' => $width,
'height' => $height,
'minWidth' => $minWidth,
'minHeight' => $minHeight,
'maxWidth' => $maxWidth,
'maxHeight' => $maxHeight,
'crop' => $crop,
);
$processedImage = $this->imageService->applyProcessingInstructions($image, $processingInstructions);
$imageUri = $this->imageService->getImageUri($processedImage);
$imageUri now holds the path to the resized image.
PS: The example you copied is from the old pibased system that no longer exists since the 7.x branch.

Related

TYPO3 extbase, the php based views do not work when migrating from 9 to 10 version

I have developed a custom TYPO3 extbase extension that was perfectly worked on 8 and 9 version of TYPO3.
Recently I upgraded my installation to TYPO3 10 version but the php based views of my TYPO3 extbase extension do not work anymore.
The error that is displayed is:
Sorry, the requested view was not found.
The technical reason is: No template was found. View could not be resolved for action "getIcal" in class "Luc\Lucevents2\Controller\EventController"
I have read the instructions in the page
https://docs.typo3.org/m/typo3/book-extbasefluid/10.4/en-us/8-Fluid/9-using-php-based-views.html, but there is nothing different from what I have already done in my extension.
So, I am very confused because there is no explanation why the code stopped to work, the above link doesn't include any instructions about deprecated code or possible changes after migration!!
Could you give me any help?
Thank you very much!
George
I hit this problem today. The documentation for "php based views" seems to be outdated.Below is a description of my setup and the solution for TYPO3 10
What I had:
My situation was that I had a Controller with a showAction() action method.
In typoscript, I had setup a new format through the type parameter. Something like
rss = PAGE
rss {
typeNum = 58978
10 =< tt_content.list.20.skevents_eventfeeds
}
For this type (parameter type=58978) I had setup a class named View\EventFeeds\ShowRss with a render() method.
TYPO3 automatically resolved this class based on the type (rss) and the action name (show). This does not work any more.
What solves this issue:
in order for TYPO3 to find the correct class with the render method, it is sufficient to set the defaultViewObjectName variable of the Controller to the correct class name for the specific action. This can be done in the controller with the following new method
public function initializeShowAction()
{
$this->defaultViewObjectName = \Skar\Skevents\View\EventFeeds\ShowRss::class;
}
So now, before calling the showAction method, defaultViewObjectName is set to my ShowRss class which produces the output.
Please note that my ShowRss class extends \TYPO3\CMS\Extbase\Mvc\View\AbstractView . According to https://docs.typo3.org/m/typo3/book-extbasefluid/master/en-us/8-Fluid/9-using-php-based-views.html this is deprecated in TYPO3 11 and will have to change for TYPO3 12
the static template is already included and all the other operations of the extension are working very well except the php based views. The ext_localconf.php looks as follows: <?php
defined('TYPO3_MODE') || die('Access denied.');
$boot = function () {
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'Luc.Lucevents2',
'Luceventsdisplay',
[
'Event' => 'list, show, delete, edit, monthview, test, ajax, deleteConfirm, showRss, getIcal, addForm, add, editForm, importeventtoforum',
'Channel' => 'list, show',
'Tag' => 'filter, show'
],
// non-cacheable actions
[
'Event' => 'list, show, delete, edit, monthview, test, ajax, deleteConfirm, showRss, getIcal, addForm, add, editForm, importeventtoforum',
'Channel' => 'list, show',
'Tag' => 'filter, show'
]
);
};
$boot();
unset($boot);
The action is registered in EventController.php and looks as follows:
/**
* action geticalaction
*
* #param \Luc\Lucevents2\Domain\Model\Event $event
* #return void
*/
public function getIcalAction(\Luc\Lucevents2\Domain\Model\Event $event = NULL)
{
$base_url = $this->request->getBaseUri();
$channel=$this->settings['channel_for_simple_users'];
if($this->request->hasArgument('duration'))
{
if ($this->request->getArgument('duration')=='6month') {
$duration=$this->request->getArgument('duration');
}
else
{
$duration='month';
}
$events = $this->eventRepository->get_events_for_rss_and_ical($duration,$channel);
$eventsarray= array();
foreach ($events as $obj){
$this->uriBuilder->setCreateAbsoluteUri(true);
$uri = $this->controllerContext->getUriBuilder()
->setUseCacheHash(false)
->uriFor('show', array("event" => $obj->getUid()));
$eventsarray[] = array($obj->getTitle(), $obj->getDescription(), $obj->getStartdatetime(),$obj->getEnddatetime(), $obj->getBuildingid(), $obj->getRoomid(), $obj->getPlace(), $obj->getCrdate(), $uri, $obj->getUid());
}
$this->view->assign('events', $eventsarray);
$this->view->assign('baseurl', $base_url);
}
else
{
$this->uriBuilder->setCreateAbsoluteUri(true);
$uri = $this->controllerContext->getUriBuilder()
->setUseCacheHash(false)
->uriFor('show', array("event" => $event->getUid()));
$this->view->assign('event', $event);
$this->view->assign('baseurl', $base_url);
$this->view->assign('uri', $uri);
}
}
Thank you very much!

TYPO3 TCA make the 'default' value dynamic

The title is rather self explanatory, but what i would like to have is a dynamic default value.
The idea behind it is to get the biggest number from a column in the database and then add one to the result. This result should be saved as the default value.
Lets take for example this code:
$GLOBALS['TCA'][$modelName]['columns']['autojobnumber'] = array(
'exclude' => true,
'label' => 'LLL:EXT:path/To/The/LLL:tx_extension_domain_model_job_autojobnumber',
'config' => [
'type' => 'input',
'size' => 10,
'eval' => 'trim,int',
'readOnly' =>1,
'default' => $result,
]
);
The SQL looks like this:
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_extension_domain_model_job');
$getBiggestNumber = $queryBuilder
->select('autojobnumber')
->from('tx_extension_domain_model_job')
->groupBy('autojobnumber')
->orderBy('autojobnumber', 'DESC')
->setMaxResults(1)
->execute()
->fetchColumn(0);
$result = $getBiggestNumber + 1;
So how can i do that "clean"?
I thought about processCmdmap_preProcess but i dont know how to pass the value to the coorisponding TCA field. Plus i do not get any results on my backend when i use the DebuggerUtility like i get them when i use processDatamap_afterAllOperations after saving the Object.
Can someone point me to the right direction?
I don't think it is supported to create a dynamic default value, see default property of input field.
What you can do however, is to create your own type (use this instead of type="input"). You can use the "user" type. (It might also be possible to create your own renderType for type="input", I never did this, but created custom renderTypes for type= "select").
You can look at the code of InputTextElement, extend that or create your own from scratch.
core code: InputTextElement
documentation for user type
more examples in FormEngine documentation
Example
(slightly modified, from documentation)
ext_localconf.php:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][<current timestamp>] = [
'nodeName' => 'customInputField',
'priority' => 40,
'class' => \T3docs\Examples\Form\Element\CustomInputElement::class,
];
CustomInputElement
<?php
declare(strict_types = 1);
namespace Myvendor\MyExtension\Backend\FormEngine\Element\CustomInputElement;
use TYPO3\CMS\Backend\Form\Element\AbstractFormElement;
// extend from AbstractFormElement
// alternatively, extend from existing Type and extend it.
class CustomInputElement extends AbstractFormElement
{
public function render():array
{
$resultArray = $this->initializeResultArray();
// add some HTML
$resultArray['html'] = 'something ...';
// ... see docs + core for more info what you can set here!
return $resultArray;
}
}

Typo3 BackendPreview getting cObj throws: Call to a member function enableFields() on null

In my BackendPreview for a custom content element in typo3 8.7 i'm trying to get a content object with following code in my own service class:
$conf = array(
'tables' => 'tt_content',
'source' => $uid,
'dontCheckPid' => 1
);
$this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$result = $this->objectManager->get(RecordsContentObject::class)->render($conf);
Doing this in frontendContext will return the cObj as expected but in BE Context, typo3 throws the exception: "Call to a member function enableFields() on null".
I've tried to initialize the configurationManager manually but no effects.
Anyone an idea?
The problem, hat the ContentObjectRenderer, (responsible for your TypoScript rendering) expect the TSFE (TypoScriptFrontendController), and since you are not in a FE context but a BE context it won't be initialized.
In theory, you can fake it, but of course it costs performance and I would not recommend it.
If you would like to have a privew, then use this approche:
https://docs.typo3.org/typo3cms/extensions/fluid_styled_content/7.6/AddingYourOwnContentElements/Index.html

TYPO3 Extbase extension: Backend FAL Upload fails

I have set up an extension with the current extension_builder in TYPO3 6.2.11.
FAL File upload in the backend is not working.
extension_builder says that file upload isn't implemented at all in extbase, but as far as I understood (cf https://github.com/helhum/upload_example), this is regarding FE upload. Correct?
I only need completely regular BE file upload - select via "Create new relation" or "Select & upload files".
The direct upload fails with "Upload failed! A file with "*" extension is expected!" (or whatever extensions I specify in TCA).
The reference creation works, but the reference is lost after saving.
This screenshot shows the two tries before saving.
And after saving, empty again:
How do I make this work? Do I have to add extra code to the repo for saving the relation? Or might there be a basic setting missing?
For tt_content, FAL relations and upload work fine.
And: As a workaround, is it possible to use a regular "Pibase" 'type' => 'group','internal_type' => 'file' field? But how would getters and setters in the model look then? Just like a regular string?
TCA:
'apprenticeship_document' => array(
'exclude' => 1,
'label' => 'LLL:EXT:stellen/Resources/Private/Language/locallang_db.xlf:tx_stellen_domain_model_institution.apprenticeship_document',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'apprenticeshipDocument',
array('maxitems' => 1),
'*'
),
),
Model as created by extension_builder:
/**
* apprenticeshipDocument
*
* #var \TYPO3\CMS\Extbase\Domain\Model\FileReference
*/
protected $apprenticeshipDocument = NULL;
/**
* Returns the apprenticeshipDocument
*
* #return \TYPO3\CMS\Extbase\Domain\Model\FileReference $apprenticeshipDocument
*/
public function getApprenticeshipDocument() {
return $this->apprenticeshipDocument;
}
/**
* Sets the apprenticeshipDocument
*
* #param \TYPO3\CMS\Extbase\Domain\Model\FileReference $apprenticeshipDocument
* #return void
*/
public function setApprenticeshipDocument(\TYPO3\CMS\Extbase\Domain\Model\FileReference $apprenticeshipDocument) {
$this->apprenticeshipDocument = $apprenticeshipDocument;
}
I have also tried to use \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> instead of \TYPO3\CMS\Extbase\Domain\Model\FileReference $apprenticeshipDocument, but that doesn't make a difference either.
Your TCA definition has an error, the first argument of getFileFieldTCAConfig should be with lower underscore, not lowerCamelCase:
'apprenticeship_document' => array(
'exclude' => 1,
'label' => 'LLL:EXT:stellen/Resources/Private/Language/locallang_db.xlf:tx_stellen_domain_model_institution.apprenticeship_document',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'apprenticeship_document',
array('maxitems' => 1),
'pdf,doc,docx'
),
),
Apart from that, "*" is not a valid file extension. You need to define a comma-separated list of file extensions (e.g. 'doc,docx,pdf'). From reading the documentation, there is no wildcard for file extensions.
File upload in FE is not implemented in the Extension Builder, but perfectly possible with the solution provided by Helmut Hummel.

Changing the height of ckeditor from a zend form

I am trying to set the height of a ckeditor I am using. Here is what I currently have:
$this->addElement('textarea', 'text_field', array(
'filters' => array('StringTrim'),
'validators' => array(
array('StringLength', true, array(0, 3000)),
),
'decorators' => array('ViewHelper'),
'required' => false,
'attribs' => array('class' => 'ckeditor'),
'label' => 'Please enter text below',
'value' => isset($this->_text_data[0]['text']) ? $this->_text_data[0]['text'] : ''
));
This comes from my form, this is then called in my .phtml file by the following:
<?=$this->element->getElement('text_field')?>
I have looked everywhere and tried adding:
'height' => '100px',
and:
'config' => array(
'toolbar' => 'Full',
'width' => '550px',
'height' => '100px',
),
But neither of these have worked. The main reason I need this is I have a text area (using the ckeditor in order to allow the input information to be formatted in a particular way) which is quite long (the default height I am assuming) but it is only ever a few lines input into the box, hence the reason I want it smaller as it takes up too much space on the page.
Thanks in advance
Iain
I made a form element and a helper using ZendX_JQuery_View_Helper_UiWidget to create a CKEditor with the jQuery adapter. Here's the code of both files :
ZendExt_Form_Element_CKEditor :
class ZendExt_Form_Element_CKEditor extends ZendX_JQuery_Form_Element_UiWidget
{
/**
* Use formCKeditor view helper by default
* #var string
*/
public $helper = 'formCKEditor';
/**
* Default ckeditor options
*
* #var array
*/
public $jQueryParams = array(
'toolbar' => 'Basic'
);
}
And ZendExt_View_Helper_FormCKEditor :
class ZendExt_View_Helper_FormCKEditor extends ZendX_JQuery_View_Helper_UiWidget
{
static $set = false;
public function formCKEditor($name, $value = null, $params = null, $attribs = null)
{
$hTextA = new Zend_View_Helper_FormTextarea();
$hTextA -> setView($this -> view);
$xhtml = $hTextA -> formTextarea($name, $value, $attribs);
$xhtml .= '<script type="text/javascript">$(document).ready(function(){$("#' . $this->_normalizeId($name) . '").ckeditor(' . (!is_null($params) ? 'function(){},' . Zend_Json_Encoder::encode($params) : '') . ')});</script>';
if (self::$set == false) {
$this -> view -> headScript() -> appendFile($this -> view -> baseUrl() . '/js/ckeditor/ckeditor.js');
$this -> view -> headScript() -> appendFile($this -> view -> baseUrl() . '/js/ckeditor/adapters/jquery.js');
self::$set = true;
}
return $xhtml;
}
}
You can use it as any other ZF form element once you copied these 2 files into :
* libraries/ZendExt/Form/Element/ for ZendExt_Form_Element_CKEditor class
* libraries/ZendExt/View/Helper/ for ZendExt_View_Helper_FormCKEditor class
and added the ZendExt namespace in your configuration file (or if you already have a library of yours and want to use it, just put both files in it and change the name of the classes to reflect yours). Then, you'll have tel ZF that ZendExt/View/Helper is a directory to look in for view helpers (in a .ini config file it would look like : resources.view.helperPath.ZendExt_View_Helper = "ZendExt/View/Helper").
Then in your code, just call $ckEditor = new ZendExt_Form_Element_CKEditor(); to create a new CKEditor. You may then add all params you want to the element using $ckEditor -> setJQueryParam($key, $value); as specified in the documentation here : http://framework.zend.com/manual/fr/zendx.jquery.html . For example : $ckEditor -> setJQueryParam('height', '100px');. I understand it's not a jQuery component, but it was the easiest way to be able to make it as everything needed is available there.
To display it, in your view just do <?=$this -> ckEditor?> and you're good.
Make sure you put your ckeditor.js and adapters/jquery.js in your public directory under /js/ckeditor/ or change the path accordingly in the helper.
You'll need to specify the dimensions of the editor when you create it (i.e., in the Javascript part). CKEditor replaces the original form element with its own code, so your changes in the dimensions will be lost.
For instance, if you create it using the jQuery interface, it would be something like the following:
var config = {
width: '550px',
height: '100px'
};
// Initialize the editor.
$('.jquery_ckeditor').ckeditor(config);
Hope that helps...