Why data is not send by form submitting (zf2 forms + filters)? - zend-framework2

I have problem:
When I fill in form and pressing add button page is reloaded, but no data is added to the database.
Code of NewsController, add action is below:
public function addAction() {
$form = new AddNewsForm();
$form->get('submit')->setValue('Add1');
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
var_dump($form->isValid());
if ($form->isValid()) {
echo "form is valid";
$objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
$blogpost = new NewsItem();
$blogpost->exchangeArray($form->getData());
$blogpost->setCreated(time());
$blogpost->setUserId(0);
$objectManager->persist($blogpost);
$objectManager->flush();
// Redirect to list of blogposts
return $this->redirect()->toRoute('news');
}
}
return array('form' => $form);
}
Class AddNewsForm is included as use \News\Form\AddNewsForm as AddNewsForm; above.
I tried to debug my code and realized, that $form->isValid() return false all time. I tried to fill in all fields of form — it says that form is not valid. If not all fields are filled in it false too.
The problem is with validation, I think, so I will add here how I assing filter to the form. This is how I assing filter to my form:
$this->setInputFilter(new AddNewsInputFilter());
Class AddNewsInputFilter is included by this:
use \News\Form\AddNewsInputFilter as AddNewsInputFilter;
I don't think it is good to paste there ~100 lines of code, so I will just give a link to files in my github repo (full code of controllers/files available here):
AddNewsForm.php — file, where I create the form
AddNewsInputFilter.php — file, where I set fil
NewsController.php — file, controller, where I call created form
Repository link — root dir of my module
So the problem is that $form->isValid(); doesn't show is form valid or not properly and I don't know why. Note, that request is getting properly and first condition is passed (but second is not passed). It is the problem, thats why I am writing here.
How I can solve it?
Thanks is advance!

try var_dump($form->getMessages()) and var_dump($form->getInputFilter()->getMessages()) in controller(after calling $form->isValid()) or in view . see what error you getting and on witch element ?
NOTICE : getMessages() will be empty if $form->isValid() has not been called yet,
UPDATE : do this in controller :
var_dump($form->isValid());
var_dump($form->getMessages())
var_dump($form->getInputFilter()->getMessages())

Related

TYPO3 - Retrieved TypoScript in itemsProcFunc are incomplete

I have following problem:
We are overriding the tt_content TCA with a custom column which has an itemsProcFunc in it's config. In the function we try to retrieve the TypoScript-Settings, so we can display the items dynamically. The problem is: In the function we don't receive all the TypoScript-Settings, which are included but only some.
'itemsProcFunc' => 'Vendor\Ext\Backend\Hooks\TcaHook->addFields',
class TcaHook
{
public function addFields($config){
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$configurationManager = $objectManager->get('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManagerInterface');
$setup = $configurationManager->getConfiguration(
\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT
);
}
$setup is now incomplete and doesn't contain the full TypoScript, for example some of the static-included TypoScript is missing.
Used TYPO3 7 LTS (7.6.18), PHP 7.0.* in composer-mode.
Does anybody know where the problem is? Is there some alternative?
You maybe misunderstood the purpose of TypoScipt. It is a way of configuration for the Frontend. The Hook you mentioned is used in the TCA, whích is a Backend part of TYPO3. TypoScript usually isn't used for backend related stuff at all, because it is bound to a specific page template record. Instead in the backend, there is the TSConfig, that can be bound to a page, but also can be added globally. Another thing you are doing wrong is the use of the ObjectManager and the ConfigurationManager, which are classes of extbase, which isn't initialized in the backend. I would recommend to not use extbase in TCA, because the TCA is cached and loaded for every page request. Instead use TSConfig or give your configuration settings directly to the TCA. Do not initialize extbase and do not use extbase classes in these hooks.
Depending on what you want to configure via TypoScript, you may want to do something like this:
'config' => [
'type' => 'select',
'renderType' => 'singleSelect',
'items' => [
['EXT:my_ext/Resources/Private/Language/locallang_db.xlf:myfield.I.0', '']
],
'itemsProcFunc' => \VENDOR\MyExt\UserFunctions\FormEngine\TypeSelectProcFunc::class . '->fillSelect',
'customSetting' => 'somesetting'
]
and then access it in your class:
class TypeSelectProcFunc{
public function fillSelect(&$params){
if( $params['customSetting'] === 'somesetting' ){
$params['items'][] = ['New item',1];
}
}
}
I had a similar problem (also with itemsProcFunc and retrieving TypoScript). In my case, the current page ID of the selected backend page was not known to the ConfigurationManager. Because of this it used the page id of the root page (e.g. 1) and some TypoScript templates were not loaded.
However, before we look at the solution, Euli made some good points in his answer:
Do not use extbase configuration manager in TCA functions
Use TSconfig instead of TypoScript for backend configuration
You may like to ask another question what you are trying to do specifically and why you need TypoScript in BE context.
For completeness sake, I tested this workaround, but I wouldn't recommend it because of the mentioned reasons and because I am not sure if this is best practice. (I only used it because I was patching an extension which was already using TypoScript in the TCA and I wanted to find out why it wasn't working. I will probably rework this part entirely.)
I am posting this in the hope that it may be helpful for similar problems.
public function populateItemsProcFunc(array &$config): array
{
// workaround to set current page id for BackendConfigurationManager
$_GET['id'] = $this->getPageId((int)($config['flexParentDatabaseRow']['pid'] ?? 0));
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$configurationManager = $objectManager->get(BackendConfigurationManager::class);
$setting = $configurationManager->getTypoScriptSetup();
$templates = $setting['plugin.']['tx_rssdisplay.']['settings.']['templates.'] ?? [];
// ... some code removed
}
protected function getPageId(int $pid): int
{
if ($pid > 0) {
return $pid;
}
$row = BackendUtility::getRecord('tt_content', abs($pid), 'uid,pid');
return $row['pid'];
}
The function getPageId() was derived from ext:news which also uses this in an itemsProcFunc but it then retrieves configuration from TSconfig. You may want to also look at that for an example: ext:news GeorgRinger\News\Hooks\ItemsProcFunc::user_templateLayout
If you look at the code in the TYPO3 core, it will try to get the current page id from
(int)GeneralUtility::_GP('id');
https://github.com/TYPO3/TYPO3.CMS/blob/90fa470e37d013769648a17a266eb3072dea4f56/typo3/sysext/extbase/Classes/Configuration/BackendConfigurationManager.php#L132
This will usually be set, but in an itemsProcFunc it may not (which was the case for me in TYPO3 10.4.14).

URL Mapping - Replacing characters in a parameter pulled from a database

I am currently trying to figure out, how to modify the parameter being integrated into the URL Mapping I am using.
static mappings =
{
"/$controller/$action?/$id?/(.$format)?"
{
constraints {
// apply constraints here
}
}
name test1: "/.../$title/..."{
controller = "study"
action = "st_show"
}
name test2: "/.../$title/..."{
controller = "search"
action = "se_show"
}
The parameter $title is pretty much a dataset, which is pulled from a database and which will get transmitted in the following format [ this is a title ]. So there are square brackets in front and behind the string and words are seperated through blanks.
If I am creating a link through g:link now with the params nested in, it gets put into the url as it is pulled from the database. What I am attempting is to create SEO-URLs, which will present a certain title of a publication devided by hyphens instead of url-encoded "%20".
Until now, I was able to generate dynamic urls looking like this:
http://localhost:8080/projectname/show/%5BAllgemeine%20Bevölkerungs[...]/782/...PARAMS...
Furthermore I already implemented it through JQuery, though it should be static and users should be able to copy the link to open up the page themselves - that wouldn't be possible when changing the url client-side while loading up the page.
Is there a way to define a function with something like replaceAll.(' ', '-'), which can be invoked onto the parameter in the mapping to replace blanks with hyphens and f.e. square brackets with an empty character?
That's pretty much, what I wasn't able to come by through the documentation.
Thank you already in advance for your help!
I managed to solve my problem by creating a service with a function containing a regex and executing this function onto the parameter title in my g:link, which I firstly converted to a string, which gets passed to the function.
<g:link controller="study" action="st_show" params="[data: data, ... title: ConversionService.convert(fieldValue(bean: path).toString(), ... data: data)]"></g:link>
And the function in the ConversionService
public static String convert(String title){
title = title.replaceAll("\\s", "-").replaceAll("[^0-9a-zA-Z\\-]", "");
return title;
}

VTiger Extension Module create custom field for Accounts Module

I'm working on a VTiger 6.4.0 Extension Module that is used to get company data when entering a company name in the Accounts module.
The module is almost finished, i retrieve data from a API and enter them in the input fields using JQuery.
But the problem is that i have some data that is not relative to the existing fields in the account information, so i'm trying to create some new custom fields.
Only i can't seem to figure out how to create a custom field for the Accounts module from within my Extension module.
I googled around and watched some posts on stackoverflow.
I came up with the following part of code, but this doesn't seem to work.
public function addKvkfield(){
$module = new Vtiger_Module();
$module->name = 'Accounts';
$module = $module->getInstance('Accounts');
$blockInstance = new Vtiger_Block();
$blockInstance->label = 'LBL_ACCOUNT_INFORMATION';
$blockInstance = $blockInstance->getInstance($blockInstance->label,$module);
$fieldInstance = new Vtiger_Field();
$fieldInstance->name = 'KvKNummer';
$fieldInstance->table = $module->basetable;
$fieldInstance->column = 'kvknummer';
$fieldInstance->columntype = 'VARCHAR(100)';
$fieldInstance->uitype = 2;
$fieldInstance->typeofdata = 'V~M';
$blockInstance->addField($fieldInstance);
}
The addKvkfield function is being called in the vtlib_handler module.postinstall (Couldn't find any information if this is the right way of doing this within a Extenstion Module)
vtlibhandler:
function vtlib_handler($modulename, $event_type) {
global $log;
if($event_type == 'module.postinstall') {
$this->addJSLinks();
$this->createConfigTable();
$this->addSettingsMenu();
$this->addKvkfield();
$this->updateLabels();
// TODO Handle post installation actions
} else if($event_type == 'module.disabled') {
// TODO Handle actions when this module is disabled.
} else if($event_type == 'module.enabled') {
// TODO Handle actions when this module is enabled.
} else if($event_type == 'module.preuninstall') {
// TODO Handle actions when this module is about to be deleted.
} else if($event_type == 'module.preupdate') {
// TODO Handle actions before this module is updated.
} else if($event_type == 'module.postupdate') {
$this->updateLabels();
// TODO Handle actions after this module is updated.
}
}
Hopefully someone can give me a push in the right direction.
Thanks in advance :)
I managed to succeed in creating the custom fields that i needed in the Accounts Module.
Thanks to the Vtiger Mailing List! :)
What did the trick was a small alteration of the code I've written:
public function addKvkfield(){
$module = Vtiger_Module::getInstance('Accounts');
$blockInstance = Vtiger_Block::getInstance('LBL_ACCOUNT_INFORMATION', $module);
$fieldInstance = new Vtiger_Field();
$fieldInstance->label = 'KvKNummer';
$fieldInstance->name = 'kvknummer';
$fieldInstance->column = $fieldInstance->name; // Good idea to keep name and columnname the same
$fieldInstance->columntype = 'VARCHAR(100)';
$fieldInstance->uitype = 1; // No need to use 2 anymore. Setting "M" below will introduce the Red asterisk
$fieldInstance->typeofdata = 'V~O';
$blockInstance->addField($fieldInstance);
}
The above code will create a (optional)Custom Field in the Account module.
If your writing a new module and never installed this module before you can just call the function in the vtlib_handler as i did in my question.
But in my case this did not work because I've already installed the plugin before adding the code to create the customfields.
So what i needed to do is call the function above on the vtlib_handler module.postupdate (this will add the custom field on a module update)
Only problem with this is that it'll get run every time the extenstion is updated.
So i suggest creating a if statement in the function to check if the field already exists in the vtiger_field dbtable if not run the script.
Hopefully i saved someone else some time by writing this all down :P
Goodluck!
Please refer below link
Add New Field in existing Module
Copy code from My Answer and create a new PHP file with ay name. Place that in CRM's root directory and Run into browser. Your Field will be added into your Module. You have to make sure about the parameters you set in code which you copy.

AJAX Form Update for a single Field

I'm trying to implement x-editable for my Form. For this is need to find a way to update the entity on a single-property-basis. The biggest headache this is giving me is the way of how a single data could be validated. To my understanding the setValidationGroup() doesn't appear to work (or i am doing this completely wrong). Here's what i tried:
if ($request->isPost()) {
$form->setData($request->getPost());
if($request->isXmlHttpRequest()) {
$filters = $form->getInputFilter();
$filters->setValidationGroup(
$this->params()->fromPost('name')
);
$form->setInputFilter($filters);
}
if ($form->isValid()) {
$objectManager->flush();
if ($request->isXmlHttpRequest()) {
$response = $this->getResponse();
$response->setStatusCode(Response::STATUS_CODE_200);
return $response;
}
} else {
$errors = $form->getMessages();
\Zend\Debug\Debug::dump($errors);
die("notvalid");
}
}
The checks for isXmlHttpReqiest serve the purpose of #1 to minify the validation-group to just one Element and #2 to send out specific responses that work with the x-editable plugin for jQuery.
Current Error: all FormFields are validated. I get an error-message for two required fields whose isEmpty-Validator are called.
I think the way you're calling setValidationGroup is wrong Sam, it's a form method, and you give it an array of field names
if($request->isXmlHttpRequest()) {
$form->setValidationGroup(array(
'name',
));
}
Solution was:
Learn to freaking set your inputFilters correctly. I don't know why i didn't get any parsing error, but there was a string error while fetching the correct inputFilters, so actually there was no inputFilter attached at all.
Since the Form has valid default data, error only occured when validating single elements.
Essence:
Start writing Unit Tests ....

Printing in icefaces

I would like to print reports in icefaces, but could got find any proper method for it. Please guide me for implementation of the same in my project.
I've used the ice:outputResource tag to let the user download a PDF report file. The resource attribute of that tag should point a managed bean property that implements com.icesoft.faces.context.Resource.
after getting idea from JOTN I'm finally able to put it together.
We can use the outputresource tag to link to any type of resource, not only static ones but also dynamically generated files(on the fly).
Let us have a look at the following example:
JSF Page:
..
..
<ice:outputResource id="outputResource1" attachment="false" fileName="File1.pdf" label="Click to download attachment" mimeType="application/pdf" rendered="true" resource="#{ReportParam01.reportfilers}" shared="false"/>
..
..
Here I've observed that the outputresource link won't appear until the file is actually generated(i case of on the fly documents).
Let us assume we wish to generate a pdf file dynamically. The following steps will link it to the above mentioned outputrespurce.
Managed Bean:
public class....{
....
// This is the resource linked to the <ice:outputresource> tag.
// Encapsulation has been done to link it.
Reource reportfilers;
....
public void createDocument() {
Document reportDoc = new Document(PageSize.A4);
File file1 = new File("Report.pdf");
PdfWriter.getInstance(reportDoc, new FileOutputStream(f));
// writing to pdf code continues
reportfilers = new FileResource(file1);
}
....
....
}
Calling the above method (if it has no exceptions) will make the link to show up and the user can download the file.

Resources