fieldset with multiple elements for recurrent code in forms using ZF2 and Doctrine2 - zend-framework

I am new to ZF2 and Doctrine2.
I am wondering, can I use Fieldsets for simillar elements repeating in Forms. There are might be several simillar elements in the same form, and there are many simillar forms.
These elements are mapped to regular fields in entities (no one-to-many or many-to-one relationships ), and there are more fields in the same entities.
If it is possible, how do I set the objects for a fieldset like that?
I am getting the following error:
Zend\Hydrator\Exception\BadMethodCallException
File:
D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-hydrator\src\ArraySerializable.php:26
Message:
Zend\Hydrator\ArraySerializable::extract expects the provided object to implement getArrayCopy()
Stack trace:
#0 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-form\src\Fieldset.php(631): Zend\Hydrator\ArraySerializable->extract(Object(OnlineFieldEvaluation\Entity\CompetencyDemonstrateEthicalAndProfessionalBehavior))
#1 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-form\src\Form.php(944): Zend\Form\Fieldset->extract()
#2 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-form\src\Form.php(303): Zend\Form\Form->extract()
#3 D:\wamp\www\onlinefieldevaluation\module\OnlineFieldEvaluation\src\OnlineFieldEvaluation\Controller\TabsController.php(170): Zend\Form\Form->bind(Object(OnlineFieldEvaluation\Entity\CompetencyDemonstrateEthicalAndProfessionalBehavior))
#4 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-mvc\src\Controller\AbstractActionController.php(82): OnlineFieldEvaluation\Controller\TabsController->editTabAction()
#5 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#6 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-eventmanager\src\EventManager.php(490): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#7 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-eventmanager\src\EventManager.php(263): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#8 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-mvc\src\Controller\AbstractController.php(118): Zend\EventManager\EventManager->triggerEventUntil(Object(Closure), Object(Zend\Mvc\MvcEvent))
#9 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-mvc\src\Controller\Plugin\Forward.php(143): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#10 D:\wamp\www\onlinefieldevaluation\module\OnlineFieldEvaluation\src\OnlineFieldEvaluation\Controller\OnlineFieldEvaluationController.php(845): Zend\Mvc\Controller\Plugin\Forward->dispatch('OnlineFieldEval...', Array)
#11 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-mvc\src\Controller\AbstractActionController.php(82): OnlineFieldEvaluation\Controller\OnlineFieldEvaluationController->showStudentEvaluationAction()
#12 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#13 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-eventmanager\src\EventManager.php(490): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#14 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-eventmanager\src\EventManager.php(263): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#15 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-mvc\src\Controller\AbstractController.php(118): Zend\EventManager\EventManager->triggerEventUntil(Object(Closure), Object(Zend\Mvc\MvcEvent))
#16 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-mvc\src\DispatchListener.php(114): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#17 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#18 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-eventmanager\src\EventManager.php(490): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#19 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-eventmanager\src\EventManager.php(263): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#20 D:\wamp\www\onlinefieldevaluation\vendor\zendframework\zend-mvc\src\Application.php(340): Zend\EventManager\EventManager->triggerEventUntil(Object(Closure), Object(Zend\Mvc\MvcEvent))
#21 D:\wamp\www\onlinefieldevaluation\public\index.php(27): Zend\Mvc\Application->run()
#22 {main}
Here is what I tried so far:
Example for Factory
<?php
class FIGradeFSFactory implements FactoryInterface
{
protected $options = array();
protected $name;
public function __construct( array $options = array())
{
$this->options = $options['options'];
$this->name = $options['name'];
}
public function createService(ServiceLocatorInterface $formElementManager)
{
$elementName = $this->options["select_element_name"];
$name = $this->getName();
$options = $this->getOptions();
return new FIGradeFS($name, $options);
}
.......... Getters and Setters
}
Example of Fieldset
<?php
namespace OnlineFieldEvaluation\Form;
class FIGradeFS extends Fieldset implements ObjectManagerAwareInterface, InputFilterProviderInterface, EventManagerAwareInterface
{
protected $objectManager;
protected $name;
protected $commentName;
protected $options;
protected $events;
protected $entityName;
/**
* #param ObjectManager $objectManager
*/
public function __construct($name = null, $options = array())
{
$this->name = $name;
$fsName = $name."FS";
parent::__construct($fsName, $options);
$this->commentName = $name . "Comment";
$this->options = $options;
$this->entityName = $options['allowed_object_binding_class'];
}
/**
*
*/
public function init()
{
$figrade = $this->name;
$figradeComment = $figrade . 'Comment';
$om = $this->getObjectManager();
$hydrator = new DoctrineHydrator($om, $this->entityName);
$hydrator->addStrategy($figrade , new FiGradeFSStrategy($figrade, $this->entityName));
$hydrator->addStrategy($figradeComment , new FiGradeFSStrategy($figradeComment, $this->entityName));
$this->setHydrator($hydrator)->setObject( new $this->entityName());
$options = $this->getOptions();
$tabPosition = $options["tabPosition"];
$qtnLetter = $options["qtnLetter"];
$isNA = $options["isNA"];
$this->add(array(
'name' => $figrade,
// 'type' => 'Zend\Form\Element\Select',
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'attributes' => array(
'required' => 'required',
'class' => 'fi-grade',
),
'options' => array(
'label' => 'Field Instructor Grade',
'object_manager' => $om,
'target_class' => $this->entityName,
'disable_inarray_validator' => true,
'property' => $figrade,
'value_options' => $this->getOptionsForSelect($isNA, $tabPosition, $qtnLetter),
),
));
//Comment popup
$this->add(array(
'type' => 'Zend\Form\Element\Textarea',
'name' => $figradeComment,
'attributes' => array(
'id' => $figradeComment,
),
'options' => array(
'label' => 'FI Comment',
),
));
}
/**
* #return array
*/
public function getInputFilterSpecification()
{
return array(
$this->name => array(
'required' => false,
),
$this->commentName => array(
'required' => false,
),
);
}
............... other methods..........................
}
Example of entity:
<?php
/**
* OnlineFieldEvaluation - ${FILE_NAME}
*
* Initial version by: Viktor
* Initial version created on: 4/23/15
*/
namespace OnlineFieldEvaluation\Entity;
// Add these import statements
use Doctrine\ORM\Mapping as ORM;
/**
* An Identity Information.
*
* #ORM\Entity
* #ORM\Table(name="form_comp_advance_rights_justice")
*
**/
class CompetencyAdvanceHumanRightsAndJustice extends CompetencyBase
{
/**
* #ORM\Column(type="string", length=10)
*/
protected $applJusticeFIGrade;
/**
* #ORM\Column(type="string", length=1000)
*/
protected $applJusticeFIGradeComment;
/**
* #ORM\Column(type="string", length=10)
*/
protected $applJusticeSSGrade;
/**
* #ORM\Column(type="string", length=10)
*/
protected $engageJusticeFIGrade;
/**
* #ORM\Column(type="string", length=1000)
*/
protected $engageJusticeFIGradeComment;
/**
* #ORM\Column(type="string", length=10)
*/
protected $engageJusticeSSGrade;
/**
* CompetencyAdvanceHumanRightsAndJustice constructor.
*/
public function __construct()
{
//calculate summary grade
// $this->calculateFiSummaryGrade();
}
public function getAllFiGrades()
{
$fiGrades[] = null;
if ($this->applJusticeFIGrade != null)
$fiGrades[] = $this->applJusticeFIGrade;
if ($this->getEngageJusticeFIGrade() != null)
$fiGrades[] = $this->engageJusticeFIGrade;
return $fiGrades;
}
...... setters and getters
}
Example of form:
<?php
/**
* OnlineFieldEvaluation - ${FILE_NAME}
*
* Initial version by: Viktor
* Initial version created on: 4/23/15
*/
namespace OnlineFieldEvaluation\Form;
use Zend\Captcha;
use Zend\Form\Element;
class CompetencyAdvanceHumanRightsAndJusticeForm extends BaseCompetencyForm
{
/**
* #param null $name
* #param null $options
*/
public function __construct($name = null, $options = null)
{
parent::__construct($name, $options);
}
/**
* needs to be set in init(), because constructor won't be aware of objectmanager
*/
public function init()
{
$this->setAttribute('method', 'post');
$this->getBaseCompetencyFormElements();
$this->add($this->getCaptionElement('applJustice'));
// Add the a fieldset for FI grade of appJustice
$this->addFIGrade('applJusticeFIGrade', $this->getTabPosition(), 'a', 'OnlineFieldEvaluation\Entity\CompetencyAdvanceHumanRightsAndJustice');
$this->add(array(
'name' => 'applJusticeSSGrade',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'required' => 'required',
),
'options' => array(
'label' => 'Student Self Grade',
'disable_inarray_validator' => true,
'value_options' => $this->getOptionsForSelect($this->getSemester(), $this->getTabPosition(), 'a'),
),
));
$this->add($this->getExampleText('applJusticeFBExample'));
$this->add($this->getExampleText('applJusticeVFPExample'));
$this->add($this->getCaptionElement('engageJustice'));
//Add FIGrade
$this->addFIGrade('engageJusticeFIGrade', $this->getTabPosition(), 'b', 'OnlineFieldEvaluation\Entity\CompetencyAdvanceHumanRightsAndJustice');
$this->add(array(
'name' => 'engageJusticeSSGrade',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'required' => 'required',
),
'options' => array(
'label' => 'Student Self Grade',
'disable_inarray_validator' => true,
'value_options' => $this->getOptionsForSelect($this->getSemester(), $this->getTabPosition(), 'b'),
),
));
$this->add($this->getExampleText('engageJusticeFBExample'));
$this->add($this->getExampleText('engageJusticeVFPExample'));
parent::init();
}
public function getAllCompetencyNamesForForm()
{
return array(
'applJustice',
'engageJustice',
);
}
}
BaseCompetencyForm :
<?php
/**
* OnlineFieldEvaluation - formFileName
*
* Initial version by: Viktor
* Initial version created on: 7/16/15
*/
namespace OnlineFieldEvaluation\Form;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use OnlineFieldEvaluation\Strategy\FIGradeFSStrategy;
use Zend\Form\Element;
use Zend\Form\Form;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
abstract class BaseCompetencyForm extends Form implements ObjectManagerAwareInterface, ServiceLocatorAwareInterface, SignatureAwareInterface
{
protected $captionService;
/**
* #var
*/
private $semester;
/**
*
* #var
*/
protected $serviceLocator;
/**
* #var \Doctrine\ORM\EntityManager
*/
private $objectManager;
private $name;
private $buildName;
private $tabName;
private $tabPosition;
protected $options;
protected $isSigned;
protected $isNA;
protected $role;
/**
* #param null $name
* #param null $options
*/
public function __construct($name = null, $options = null)
{
$this->name = $name;
$this->options = $options;
parent::__construct($name, $options);
$this->semester = $options['semester'];
$this->buildName = $options['buildName'];
$this->tabPosition = $options['tabPosition'];
$this->tabName = $options['tabName'];
$this->isSigned= $options['isSigned'];
$this->isNA = $options['isNA'];
$this->role = $options['role'];
}
/**
*
*/
public function init()
{
$om = $this->getObjectManager();
$this->setAttribute('name', $this->getName());
$this->setAttribute('class', 'competency-form');
$hydrator = new DoctrineHydrator($om);
// $hydrator->setObject($this->getEntityInstanceFromBuildName($this->buildName));
// $hydrator->addStrategy('applJusticeFIGradeFS', new FiGradeFSStrategy());
$entityName = 'OnlineFieldEvaluation\Entity\\' . $this->buildName;
foreach ($this->getAllCompetencyNamesForForm() as $compName) {
$figrade = $compName . 'FIGrade';
$figradeComment = $figrade . 'Comment';
// $hydrator->addStrategy($figrade, new FiGradeFSStrategy($figrade, $entityName));
// $hydrator->addStrategy($figradeComment, new FiGradeFSStrategy($figradeComment, $entityName));
// TODO: Here Apply captionService
// $competencyCaption = $compName.'Caption';
//
// $hydrator->addStrategy($competencyCaption, new AssignCaptionsStrategy($competencyCaption, $entityName));
}
// $this->setHydrator($hydrator);
// disable elements if the form is signed
if($this->isSigned)
{
$this->disableElements($this->getIterator());
}
}
/**
* #param $formElements
*/
protected function disableElements($formElements)
{
foreach ($formElements as $elementOrFieldset) {
if ($elementOrFieldset instanceof \Zend\Form\FieldsetInterface) {
$fsElements = $elementOrFieldset->getIterator();
$this->disableElements($fsElements);
} else {
$elementOrFieldset->setAttribute('disabled', 'disabled');
}
}
}
/**
* #param $name
* #return mixed
*/
protected function getCaptionElement($name)
{
$formElementManager = $this->serviceLocator;
$options = [
'name' => $name,
'type' => 'CompetencyElementCaption',
'shared' => false,
'attributes' => array(
'class' => 'competency-task',
'disabled' => 'disabled',
'required' => 'required',
),
'options' => array(
'label' => 'test label'
),
];
$captionElement = $formElementManager->get('CompetencyElementCaption', $options);
// $captionElement->setOptions($options);
return $captionElement;
}
/**
* #param $name
* #return mixed
*/
protected function getExampleText($name)
{
$formElementManager = $this->serviceLocator;
$options = [
'name' => $name,
'type' => 'CompetencyExampleText',
'shared' => false,
'attributes' => array(
'class' => 'competency-task',
'disabled' => 'disabled',
'required' => 'required',
),
'options' => array(
'label' => 'test label'
),
];
$exampleTextElement = $formElementManager->get('CompetencyExampleText', $options);
// $captionElement->setOptions($options);
return $exampleTextElement;
}
/**
*
*/
private function getEntityInstanceFromBuildName($buildName)
{
$entityName = 'OnlineFieldEvaluation\Entity\\' . $buildName;
return new $entityName();
}
/**
*
*/
public function getBaseCompetencyFormElements()
{
$this->add(array(
'name' => 'id',
// 'type' => 'Hidden',
'options' => array(
'label' => 'ID',
),
));
$this->add(array(
'type' => 'Hidden',
'name' => 'tabName',
'attributes' => array(
'value' => $this->tabName
)
));
$this->add(array(
'type' => 'Hidden',
'name' => 'buildName',
'attributes' => array(
'class' => 'build-name',
'value' => $this->buildName
)
));
$this->add(array(
'type' => 'Hidden',
'name' => 'semester',
'attributes' => array(
'value' => $this->semester
)
));
$this->add(array(
'type' => 'Hidden',
'name' => 'tabPosition',
'attributes' => array(
'value' => $this->tabPosition,
),
));
$this->add(array(
'type' => 'Hidden',
'name' => 'isSigned',
'attributes' => array(
'value' => $this->isSigned,
),
));
$this->add(array(
'name' => 'studEvalId',
'type' => 'Hidden',
'options' => array(
'label' => 'Student Evaluation ID',
),
));
$this->add(array(
'type' => 'Hidden',
'name' => 'fiSummaryGrade',
'attributes' => array(
'class' => 'grades-summary',
'label' => 'FI Summary Grade',
)
));
$this->add(array(
'name' => 'csrf',
'type' => 'Zend\Form\Element\Csrf',
'options' => array(
'csrf_options' => array(
'timeout' => 7200
)
)
));
$this->add(array(
'name' => 'submitbutton',
'type' => 'Submit',
'attributes' => array(
'value' => 'Save',
'id' => 'submitbutton',
),
'options' => array(
'label' => 'Save It',
),
));
}
/**
* #param mixed $semester
*/
public function setSemester($semester)
{
$this->semester = $semester;
}
/**
* #return mixed
*/
public function getSemester()
{
return $this->semester;
}
/**
* #param $semester
* #return array
*/
public function getOptionsForSelect($semester, $tabPosition, $qtnLetter)
{
$question = ($tabPosition - 1) . $qtnLetter;
$naQuestions = array('3a', '3b', '4b', '5a', '5b', '5c', '8c', '9a', '9b', '9c');
$valueOptions = null;
// if ($semester === 1 && in_array($question, $naQuestions)) {
if ($this->isNA === true && in_array($question, $naQuestions)) {
$valueOptions = array(
'na' => 'N/A',
'0' => '0',
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4',
'5' => '5',
'6' => '6',
'7' => '7',
'8' => '8',
'9' => '9',
'10' => '10',
);
} else {
$valueOptions = array(
'0' => '0',
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4',
'5' => '5',
'6' => '6',
'7' => '7',
'8' => '8',
'9' => '9',
'10' => '10'
);
}
return $valueOptions;
}
/**
* #return mixed
*/
public function getObjectManager()
{
return $this->objectManager;
}
/**
* #param ObjectManager $objectManager
* #return $this
*/
public function setObjectManager(ObjectManager $objectManager)
{
$this->objectManager = $objectManager;
// return $this;
}
/**
* #param ServiceLocatorInterface $sl
*/
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
/**
* #return mixed
*/
public function getServiceLocator()
{
return $this->serviceLocator;
}
/**
* #param null $name
* #param null $bindingClass
* #return mixed
*/
protected function addFIGrade($name = null, $tabPosition = null, $qtnLetter = null, $bindingClass = null)
{
// $options = $this->getFIFieldSetOptions($name, $this->getSemester(), $tabPosition, $qtnLetter, $bindingClass);
$isNA = $this->getIsNA();
$options = $this->getFIFieldSetOptions($name, $isNA, $tabPosition, $qtnLetter, $bindingClass);
$formElementManager = $this->serviceLocator;
$fieldset = $formElementManager->get('FIGradeFS', array('name' => $name, 'options' => $options));
$this->add($fieldset);
}
/**
* #param null $name
* #param array $options
*/
protected function getFIFieldSetOptions($name = null, $isNA = 0, $tabPosition = null, $qtnLetter = null, $bindingClass = null)
{
return array(
'use_as_base_fieldset' => false,
'object_manager' => $this->getObjectManager(),
'disable_inarray_validator' => true,
'allowed_object_binding_class' => $bindingClass,
'select_element_name' => $name,
// 'semester' => $semester,
'isNA' => $isNA,
'tabPosition' => $tabPosition,
'qtnLetter' => $qtnLetter
);
}
/**
* #param null $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* #return null
*/
public function getName()
{
return $this->name;
}
/**
* #param null $options
*/
public function setOptions($options)
{
$this->options = $options;
}
/**
* #return null
*/
public function getOptions()
{
return $this->options;
}
/**
* #param mixed $buildName
*/
public function setBuildName($buildName)
{
$this->buildName = $buildName;
}
/**
* #return mixed
*/
public function getBuildName()
{
return $this->buildName;
}
/**
* #param mixed $tabPosition
*/
public function setTabPosition($tabPosition)
{
$this->tabPosition = $tabPosition;
}
/**
* #return mixed
*/
public function getTabPosition()
{
return $this->tabPosition;
}
/**
* Order matters in this function
*/
abstract public function getAllCompetencyNamesForForm();
/**
* #param $isSigned
*/
public function setIsSigned($isSigned)
{
$this->isSigned = $isSigned;
}
/**
* #return mixed
*/
public function getIsSigned()
{
return $this->isSigned;
}
/**
* #return mixed
*/
public function getIsNA()
{
return $this->isNA;
}
/**
* #param mixed $isNA
*/
public function setIsNA($isNA)
{
$this->isNA = $isNA;
}
}

Related

Laravel Backpack Inline Create not showing button to insert NEW ITEMS

I can't get the ADD NEW ITEM Button to that opens the modal with Inline create
But, strangely, in the primary class, I see the items that are related, inside a box, showed as buttons with an [x] to delete them.
Primary Class (FairCrudController.php)
namespace App\Http\Controllers\Admin;
use App\Http\Requests\FairRequest;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
/**
* Class FairCrudController
* #package App\Http\Controllers\Admin
* #property-read \Backpack\CRUD\app\Library\CrudPanel\CrudPanel $crud
*/
class FairCrudController extends CrudController
{
use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\InlineCreateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\FetchOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\BulkDeleteOperation;
use \Backpack\EditableColumns\Http\Controllers\Operations\MinorUpdateOperation;
/**
* Configure the CrudPanel object. Apply settings to all operations.
*
* #return void
*/
public function setup()
{
CRUD::setModel(\App\Models\Fair::class);
CRUD::setRoute(config('backpack.base.route_prefix') . '/fair');
CRUD::setEntityNameStrings('feria', 'Ferias');
}
/**
* Define what happens when the List operation is loaded.
*
* #see https://backpackforlaravel.com/docs/crud-operation-list-entries
* #return void
*/
protected function setupListOperation()
{
CRUD::addColumn([
'name' => 'name',
'type' => 'editable_text',
'label' => 'Nombre',
'underlined' => true,
'min_width' => '120px',
'select_on_click' => false,
'save_on_focusout' => false,
'auto_update_row' => true,
]);
CRUD::column('hero_image')->label('Imagen')->type('image');
CRUD::column('start_at')->label('Empieza');
CRUD::column('end_at')->label('Termina');
CRUD::column('date_limit')->label('Límite');
CRUD::addColumn([
'name' => 'status',
'label' => 'Activada',
'type' => 'editable_switch',
'color' => 'success',
'onLabel' => '✓',
'offLabel' => '✕',
]);
$this->crud->enableBulkActions();
$this->crud->setDefaultPageLength(100);
$this->crud->orderBy('start_at', 'DESC');
}
/**
* Define what happens when the Create operation is loaded.
*
* #see https://backpackforlaravel.com/docs/crud-operation-create
* #return void
*/
protected function setupCreateOperation()
{
CRUD::setValidation(FairRequest::class);
CRUD::field('name')->label('Nombre');
CRUD::field('website')->label('Sitio Web');
CRUD::field('invoice_prefix')->label('Prefijo de Facturas');
CRUD::field('address')->label('Dirección');
CRUD::field('city')->label('Ciudad');
CRUD::field('state')->label('Estado/Provincia');
CRUD::field('zip_code')->label('Código Postal');
CRUD::field('country')->label('Pais');
CRUD::field('contactperson')->type('relationship')->label('Personas de Contacto');
CRUD::field('contact_persons_copy')->label('Poner en copia de los emails (separados por punto y coma)');
CRUD::field('start_at')->label('Comienza');
CRUD::field('end_at')->label('Termina');
CRUD::field('date_limit')->label('Límite');
$this->crud->addField([
'label' => "Imagen de Presentación",
'name' => "hero_image",
'type' => 'image',
'crop' => true,
'aspect_ratio' => 0,
]);
$this->crud->addField([
'type' => "relationship",
'name' => 'images',
'label' => 'Imágenes',
'ajax' => true,
'inline_create' => true,
]);
$this->crud->addField([
'type' => "relationship",
'name' => 'dossiers',
'ajax' => true,
'inline_create' => [ 'entity' => 'dossier' ],
'data_source' => backpack_url('fair/fetch/dossier')
]);
$this->crud->addField([
'type' => "relationship",
'name' => 'newsletters',
'ajax' => true,
'inline_create' => true,
]);
CRUD::field('stands')->type('relationship')->label('Stands');
CRUD::field('status')->label('Activa')->default(1);
}
/**
* Define what happens when the Update operation is loaded.
*
* #see https://backpackforlaravel.com/docs/crud-operation-update
* #return void
*/
protected function setupUpdateOperation()
{
$this->setupCreateOperation();
}
/**
* Define what happens when the View operation is loaded.
*
* #see https://backpackforlaravel.com/docs/5.x/crud-operation-show
* #return void
*/
protected function setupShowOperation()
{
CRUD::column('name')->label('Nombre');
CRUD::column('website')->label('Sitio Web');
CRUD::column('invoice_prefix')->label('Prefijo de Facturas');
CRUD::column('address')->label('Dirección');
CRUD::column('city')->label('Ciudad');
CRUD::column('state')->label('Estado/Provincia');
CRUD::column('zip_code')->label('Código Postal');
CRUD::column('country')->label('Pais');
CRUD::column('contact_persons_copy')->label('Poner en copia de los emails (separados por punto y coma)');
CRUD::column('start_at')->label('Comienza');
CRUD::column('end_at')->label('Termina');
CRUD::column('date_limit')->label('Límite');
CRUD::column('hero_image')->label('Imagen')->type('image');
CRUD::column('status')->label('Activada')->type('check');
}
public function setupInlineCreateOperation() {
$this->setupCreateOperation();
}
protected function fetchDossier()
{
return $this->fetch(\App\Models\Dossier::class);
}
}
Secondary Class (DossierCrudController.php)
namespace App\Http\Controllers\Admin;
use App\Http\Requests\DossierRequest;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
/**
* Class DossierCrudController
* #package App\Http\Controllers\Admin
* #property-read \Backpack\CRUD\app\Library\CrudPanel\CrudPanel $crud
*/
class DossierCrudController extends CrudController
{
use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\InlineCreateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\BulkDeleteOperation;
use \Backpack\EditableColumns\Http\Controllers\Operations\MinorUpdateOperation;
/**
* Configure the CrudPanel object. Apply settings to all operations.
*
* #return void
*/
public function setup()
{
CRUD::setModel(\App\Models\Dossier::class);
CRUD::setRoute(config('backpack.base.route_prefix') . '/dossier');
CRUD::setEntityNameStrings('dossier de la feria', 'dossiers de la feria');
}
/**
* Define what happens when the List operation is loaded.
*
* #see https://backpackforlaravel.com/docs/crud-operation-list-entries
* #return void
*/
protected function setupListOperation()
{
CRUD::addColumn([
'name' => 'fair_id',
'label' => 'Feria',
'type' => 'editable_select',
'options' => \App\Models\Fair::all()->pluck('name', 'id')->toArray(),
'underlined' => true,
'save_on_focusout' => true,
'save_on_change' => true,
'auto_update_row' => true,
]);
CRUD::addColumn([
'name' => 'name',
'type' => 'editable_text',
'label' => 'Nombre',
'underlined' => true,
'min_width' => '120px',
'select_on_click' => false,
'save_on_focusout' => false,
'auto_update_row' => true,
]);
CRUD::addColumn([
'name' => 'status',
'label' => 'Activado',
'type' => 'editable_switch',
'color' => 'success',
'onLabel' => '✓',
'offLabel' => '✕',
]);
$this->crud->enableBulkActions();
$this->crud->setDefaultPageLength(100);
$this->crud->orderBy('fair_id', 'ASC');
}
/**
* Define what happens when the Create operation is loaded.
*
* #see https://backpackforlaravel.com/docs/crud-operation-create
* #return void
*/
protected function setupCreateOperation()
{
CRUD::setValidation(DossierRequest::class);
CRUD::field('fair')->type('select')->label('Feria');
CRUD::field('name')->label('Nombre');
CRUD::field('status')->label('Activo')->default(1);
$this->crud->addField([
'label' => "Archivo (Tamaño: 16MB máx.)",
'name' => "file",
'upload' => true,
'type' => 'upload',
]);
}
/**
* Define what happens when the Update operation is loaded.
*
* #see https://backpackforlaravel.com/docs/crud-operation-update
* #return void
*/
protected function setupUpdateOperation()
{
$this->setupCreateOperation();
}
protected function setupShowOperation()
{
CRUD::column('fair')->label('Feria');
CRUD::column('name')->label('Nombre');
CRUD::column('file')->label('Archivo')->type('file');
CRUD::column('status')->label('Activado')->type('check');
}
public function setupInlineCreateOperation() {
$this->setupCreateOperation();
}
}
/routes/backpack/custom.php
....
Route::get('fair/fetch/dossier', [DossierCrudController::class, "fetchDossier"]);
....
Fair.php Model
use App\Models\Dossier;
...
public function dossiers()
{
return $this->hasMany(Dossier::class);
}
....
Dossier.php Model
use App\Models\Fair;
...
public function fair()
{
return $this->belongsTo(Fair::class);
}
....

Validate File Extension IN Drupal 8 Entity Form

I have an Entity in Drupal 8 named visual_tracker_entity Here is my entity,
/**
* #file
* Contains \Drupal\visual_tracker\Entity\VisaulTrackerEntity.
*/
namespace Drupal\visual_tracker\Entity;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityChangedTrait;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\visual_tracker\VisaulTrackerEntityInterface;
use Drupal\user\UserInterface;
/**
* Defines the Visaul tracker entity entity.
*
* #ingroup visual_tracker
*
* #ContentEntityType(
* id = "visaul_tracker_entity",
* label = #Translation("Visaul tracker entity"),
* handlers = {
* "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
* "list_builder" = "Drupal\visual_tracker\VisaulTrackerEntityListBuilder",
* "views_data" = "Drupal\visual_tracker\Entity\VisaulTrackerEntityViewsData",
*
* "form" = {
* "default" = "Drupal\visual_tracker\Form\VisaulTrackerEntityForm",
* "add" = "Drupal\visual_tracker\Form\VisaulTrackerEntityForm",
* "edit" = "Drupal\visual_tracker\Form\VisaulTrackerEntityForm",
* "delete" = "Drupal\visual_tracker\Form\VisaulTrackerEntityDeleteForm",
* },
* "access" = "Drupal\visual_tracker\VisaulTrackerEntityAccessControlHandler",
* "route_provider" = {
* "html" = "Drupal\visual_tracker\VisaulTrackerEntityHtmlRouteProvider",
* },
* },
* base_table = "visaul_tracker_entity",
* admin_permission = "administer visaul tracker entity entities",
* entity_keys = {
* "id" = "id",
* "address" = "address",
* "lat"="lat",
* "lng" = "lng"
* },
* links = {
* "canonical" = "/admin/structure/visaul_tracker_entity/{visaul_tracker_entity}",
* "add-form" = "/admin/structure/visaul_tracker_entity/add",
* "edit-form" = "/admin/structure/visaul_tracker_entity/{visaul_tracker_entity}/edit",
* "delete-form" = "/admin/structure/visaul_tracker_entity/{visaul_tracker_entity}/delete",
* "collection" = "/admin/structure/visaul_tracker_entity",
* },
* field_ui_base_route = "visaul_tracker_entity.settings"
* )
*/
class VisaulTrackerEntity extends ContentEntityBase implements VisaulTrackerEntityInterface {
use EntityChangedTrait;
/**
* {#inheritdoc}
*/
public static function preCreate(EntityStorageInterface $storage_controller, array &$values) {
parent::preCreate($storage_controller, $values);
$values += array(
'user_id' => \Drupal::currentUser()->id(),
);
}
/**
* {#inheritdoc}
*/
public function getName() {
return $this->get('name')->value;
}
/**
* {#inheritdoc}
*/
public function setName($name) {
$this->set('name', $name);
return $this;
}
/**
* {#inheritdoc}
*/
public function getAddress() {
return $this->get('address')->value;
}
/**
* {#inheritdoc}
*/
public function setAddress($address) {
$this->set('address', $address);
return $this;
}
/**
* {#inheritdoc}
*/
public function getLatittude() {
return $this->get('lat')->value;
}
/**
* {#inheritdoc}
*/
public function setLatitude($lat) {
$this->set('lat', $lat);
return $this;
}
/**
* {#inheritdoc}
*/
public function getLongitude() {
return $this->get('lng')->value;
}
/**
* {#inheritdoc}
*/
public function setLongitude($lng) {
$this->set('lng', $lng);
return $this;
}
/**
* {#inheritdoc}
*/
public function getCreatedTime() {
return $this->get('created')->value;
}
/**
* {#inheritdoc}
*/
public function setCreatedTime($timestamp) {
$this->set('created', $timestamp);
return $this;
}
/**
* {#inheritdoc}
*/
public function getOwner() {
return $this->get('user_id')->entity;
}
/**
* {#inheritdoc}
*/
public function getOwnerId() {
return $this->get('user_id')->target_id;
}
/**
* {#inheritdoc}
*/
public function setOwnerId($uid) {
$this->set('user_id', $uid);
return $this;
}
/**
* {#inheritdoc}
*/
public function setOwner(UserInterface $account) {
$this->set('user_id', $account->id());
return $this;
}
/**
* {#inheritdoc}
*/
public function isPublished() {
return (bool) $this->getEntityKey('status');
}
/**
* {#inheritdoc}
*/
public function setPublished($published) {
$this->set('status', $published ? NODE_PUBLISHED : NODE_NOT_PUBLISHED);
return $this;
}
/**
* {#inheritdoc}
*/
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields['id'] = BaseFieldDefinition::create('integer')
->setLabel(t('ID'))
->setDescription(t('The ID of the Visaul tracker entity entity.'))
->setReadOnly(TRUE);
$fields['uuid'] = BaseFieldDefinition::create('uuid')
->setLabel(t('UUID'))
->setDescription(t('The UUID of the Visaul tracker entity entity.'))
->setReadOnly(TRUE);
$fields['user_id'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Authored by'))
->setDescription(t('The user ID of author of the Visaul tracker entity entity.'))
->setRevisionable(TRUE)
->setSetting('target_type', 'user')
->setSetting('handler', 'default')
->setDefaultValueCallback('Drupal\node\Entity\Node::getCurrentUserId')
->setTranslatable(TRUE)
->setDisplayOptions('view', array(
'label' => 'hidden',
'type' => 'author',
'weight' => 0,
))
->setDisplayOptions('form', array(
'type' => 'entity_reference_autocomplete',
'weight' => 5,
'settings' => array(
'match_operator' => 'CONTAINS',
'size' => '60',
'autocomplete_type' => 'tags',
'placeholder' => '',
),
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['my_new_file'] = BaseFieldDefinition::create('file')
->setLabel(t('My New File'))
->setDescription(t('The name of the Visaul tracker entity entity.'))
->setDefaultValue('')
->setDisplayOptions('view', array(
'label' => 'above',
'type' => 'file',
'weight' => -4,
))
->setDisplayOptions('form', array(
'type' => 'file',
'weight' => -4,
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['address'] = BaseFieldDefinition::create('string')
->setLabel(t('Address'))
->setDescription(t('The addres of the Visaul tracker entity entity.'))
->setSettings(array(
'max_length' => 250,
'text_processing' => 0,
))
->setDefaultValue('')
->setDisplayOptions('view', array(
'label' => 'above',
'type' => 'string',
'weight' => -4,
))
->setDisplayOptions('form', array(
'type' => 'string_textfield',
'weight' => -4,
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['lat'] = BaseFieldDefinition::create('string')
->setLabel(t('Latitiude'))
->setDescription(t('The latiitude of the Visaul tracker entity entity.'))
->setSettings(array(
'max_length' => 50,
'text_processing' => 0,
))
->setDefaultValue('')
->setDisplayOptions('view', array(
'label' => 'above',
'type' => 'string',
'weight' => -4,
))
->setDisplayOptions('form', array(
'type' => 'string_textfield',
'weight' => -4,
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['lng'] = BaseFieldDefinition::create('string')
->setLabel(t('Longitude'))
->setDescription(t('The name of the Visaul tracker entity entity.'))
->setSettings(array(
'max_length' => 50,
'text_processing' => 0,
))
->setDefaultValue('')
->setDisplayOptions('view', array(
'label' => 'above',
'type' => 'string',
'weight' => -4,
))
->setDisplayOptions('form', array(
'type' => 'string_textfield',
'weight' => -4,
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['status'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Publishing status'))
->setDescription(t('A boolean indicating whether the Visaul tracker entity is published.'))
->setDefaultValue(TRUE);
$fields['langcode'] = BaseFieldDefinition::create('language')
->setLabel(t('Language code'))
->setDescription(t('The language code for the Visaul tracker entity entity.'))
->setDisplayOptions('form', array(
'type' => 'language_select',
'weight' => 10,
))
->setDisplayConfigurable('form', TRUE);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created'))
->setDescription(t('The time that the entity was created.'));
$fields['changed'] = BaseFieldDefinition::create('changed')
->setLabel(t('Changed'))
->setDescription(t('The time that the entity was last edited.'));
return $fields;
}
}
I need add validation rule for file type field. The default file type is come with .txt extension. I want to only allow .xls and .xlsx .
This is the file filed,
$fields['my_new_file'] = BaseFieldDefinition::create('file')
->setLabel(t('My New File'))
->setDescription(t('The name of the Visaul tracker entity entity.'))
->setDefaultValue('')
->setDisplayOptions('view', array(
'label' => 'above',
'type' => 'file',
'weight' => -4,
))
->setDisplayOptions('form', array(
'type' => 'file',
'weight' => -4,
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
Please help me.
I got the answer after digging drupal 8 core APIs.
If we're using a file field, then we can set the "file_extensions" setting. You can find out more information about a "file" type by going to the FileItem API.
$fields['my_new_file'] = BaseFieldDefinition::create('file')
->setSetting('file_extensions', 'xls xlsx');

TYPO3 Extbase 1:n relation objects not exposed in view

I'm currently learning extbase and fluid. I read along this SO post TYPO3 extbase & IRRE: add existing records with 'foreign_selector' to set up a relation in my extension. I got roles and people. N people can have M roles. Now everything works fine in the backend. While in the frontend I don't see the objects when I use f:debug. My problem is that the relation isn't correctly resolved by extbase (I think?).
This is my relation class:
<?php
namespace Vendor\People\Domain\Model;
/**
* Class PersonRoleRelation
* #scope prototype
* #entity
* #package Vendor\People\Domain\Model
*/
class PersonRelation extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
/**
* #var \Vendor\People\Domain\Model\Person
*/
protected $person;
/**
* #var \Vendor\People\Domain\Model\Role
*/
protected $role;
/**
* #param \Vendor\People\Domain\Model\Person $person
*/
public function setPerson($person) {
$this->person = $person;
}
/**
* #return \Vendor\People\Domain\Model\Person
*/
public function getPerson() {
return $this->person;
}
/**
* #param \Vendor\People\Domain\Model\Role $role
*/
public function setRole($role) {
$this->role = $role;
}
/**
* #return \Vendor\People\Domain\Model\Role
*/
public function getRole() {
return $this->role;
}
}
This is entity person:
<?php
namespace Vendor\People\Domain\Model;
/**
* Class Person
* #scope prototype
* #entity
* #package Vendor\People\Domain\Model
*/
class Person extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
public function __construct() {
$this->initStorageObjects();
}
/**
* #return void
*/
protected function initStorageObjects() {
$this->roles = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
}
/**
* Roles
* #var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Vendor\People\Domain\Model\PersonRelation>
*/
protected $roles = NULL;
/**
* the person's first name
* #var string
* #validate StringLength(minimum = 3, maximum = 50)
*/
protected $firstname;
/**
* the person's last name
* #var string
* #validate StringLength(minimum = 3, maximum = 50)
*/
protected $lastname;
/**
* the person's responsibilities within the company
* #var string
*/
protected $role;
/**
* Photo
* #var \TYPO3\CMS\Extbase\Domain\Model\FileReference
*/
protected $photo;
/**
* detail text about the person
* #var string
* #dontvalidate
*/
protected $description;
/**
* #param string $firstname
* #return void
*/
public function setFirstname($firstname) {
$this->firstname = $firstname;
}
/**
* #return string
*/
public function getFirstname() {
return $this->firstname;
}
/**
* #param string $lastname
* #return void
*/
public function setLastname($lastname) {
$this->lastname = $lastname;
}
/**
* #return string
*/
public function getLastname() {
return $this->lastname;
}
/**
* #param string $role
* #return void
*/
public function setRole($role) {
$this->role = $role;
}
/**
* #return string
*/
public function getRole() {
return $this->role;
}
/**
* #param string $description
* #return void
*/
public function setDescription($description) {
$this->description = $description;
}
/**
* #return string
*/
public function getDescription() {
return $this->description;
}
/**
* #param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $photo
* #return void
*/
public function setPhoto($photo) {
$this->photo = $photo;
}
/**
* #return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference>
*/
public function getPhoto() {
return $this->photo;
}
/**
* #return\TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Vendor\People\Domain\Model\PersonRelation>
*/
public function getRoles() {
return $this->roles;
}
}
?>
and this is role:
<?php
namespace Vendor\People\Domain\Model;
/**
* Class Role
* #scope prototype
* #entity
* #package Vendor\People\Domain\Model
*/
class Role extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
/**
* the role's title
* #var string
* #validate StringLength(minimum = 3, maximum = 50)
*/
protected $name;
public function __construct() {
}
/**
* #param string $name
* #return void
*/
public function setName($name) {
$this->name = $name;
}
/**
* #return string
*/
public function getName() {
return $this->name;
}
}
?>
ext_tables.sql:
CREATE TABLE tx_people_domain_model_person (
uid int(11) NOT NULL auto_increment,
pid int(11) DEFAULT '0' NOT NULL,
tstamp int(11) DEFAULT '0' NOT NULL,
crdate int(11) DEFAULT '0' NOT NULL,
deleted tinyint(4) DEFAULT '0' NOT NULL,
hidden tinyint(4) DEFAULT '0' NOT NULL,
firstname varchar(225) DEFAULT '' NOT NULL,
lastname varchar(225) DEFAULT '' NOT NULL,
role varchar(225) DEFAULT '' NOT NULL,
roles int(11) unsigned DEFAULT '0' NOT NULL,
description mediumtext DEFAULT '' NOT NULL,
photo mediumblob NOT NULL,
PRIMARY KEY (uid),
KEY parent (pid)
) ENGINE=InnoDB;
CREATE TABLE tx_people_domain_model_role (
uid int(11) NOT NULL auto_increment,
pid int(11) DEFAULT '0' NOT NULL,
tstamp int(11) DEFAULT '0' NOT NULL,
crdate int(11) DEFAULT '0' NOT NULL,
deleted tinyint(4) DEFAULT '0' NOT NULL,
hidden tinyint(4) DEFAULT '0' NOT NULL,
name varchar(225) DEFAULT '' NOT NULL,
PRIMARY KEY (uid)
KEY parent (pid)
) ENGINE=InnoDB;
CREATE TABLE tx_people_domain_model_person_role_rel (
uid_local int(11) unsigned DEFAULT '0' NOT NULL,
uid_foreign int(11) unsigned DEFAULT '0' NOT NULL,
sorting int(11) unsigned DEFAULT '0' NOT NULL,
KEY uid_local (uid_local),
KEY uid_foreign (uid_foreign)
) ENGINE=InnoDB;
TCA config:
tx_people_domain_model_person.php:
<?php
return array(
'ctrl' => array(
'title' => 'Person',
'label' => 'firstname',
'label_alt' => ',lastname',
'label_alt_force' => TRUE,
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'dividers2tabs' => TRUE,
'delete' => 'deleted',
'enablecolumns' => array(
'disabled' => 'hidden',
),
'iconfile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('people') . 'ext_icon.gif'
),
'types' => array(
'1' => array('showitem' => 'firstname, lastname, role, description, photo, roles')
),
'columns' => array(
'hidden' => array(
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.hidden',
'config' => array(
'type' => 'check'
)
),
'firstname' => array(
'exclude' => 0,
'label' => 'Vorname',
'config' => array(
'type' => 'input',
'size' => 225,
)
),
'lastname' => array(
'exclude' => 0,
'label' => 'Nachname',
'config' => array(
'type' => 'input',
'size' => 225,
)
),
'role' => array(
'exclude' => 0,
'label' => 'Rolle',
'config' => array(
'type' => 'input',
'size' => 225,
)
),
'description' => array(
'exclude' => 0,
'label' => 'Beschreibung',
'config' => array(
'type' => 'text',
)
),
'roles' => array(
'label' => 'Rollen',
'config' => array(
'type' => 'select',
'size' => 10,
'maxitems' => 3,
'foreign_table' => 'tx_people_domain_model_role',
'MM' => 'tx_people_domain_model_person_role_rel',
// 'foreign_table' => 'tx_people_domain_model_person_role_rel',
// 'foreign_field' => 'uid_person',
// 'foreign_label' => 'uid_role',
// 'foreign_selector' => 'uid_role',
// 'foreign_unique' => 'uid_role',
// 'foreign_sortby' => 'sorting',
),
),
'photo' => array(
'exclude' => 0,
'label' => 'Foto',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig('photo', array(
'appearance' => array(
'createNewRelationLinkTitle' => 'Bild hinzufügen',
'collapseAll' => FALSE,
),
'maxitems' => 1,
), $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'])
),
),
);
?>
tx_domain_model_person_role_rel.php:
<?php
return array(
'ctrl' => array(
'title' => 'Relation Table',
'hideTable' => TRUE,
'sortBy' => 'sorting',
// 'tstamp' => 'tstamp',
// 'crdate' => 'crdate',
// 'dividers2tabs' => TRUE,
// 'delete' => 'deleted',
// 'enablecolumns' => array(
// 'disabled' => 'hidden',
// ),
// 'iconfile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('people') . 'ext_icon.gif'
),
'types' => array(
'0' => array('showitem' => 'uid_person, uid_role')
),
'palettes' => array(),
'columns' => array(
// 'hidden' => array(
// 'exclude' => 1,
// 'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.hidden',
// 'config' => array(
// 'type' => 'check'
// )
// ),
'uid_local' => array(
'label' => 'Person',
'config' => array(
'type' => 'select',
'MM' => 'tx_people_domain_model_person_role_rel',
'foreign_table' => 'tx_people_domain_model_person',
'size' => 1,
'minitems' => 0,
'maxitems' => 1,
),
),
'uid_foreign' => array(
'label' => 'Rolle',
'config' => array(
'type' => 'select',
'MM' => 'tx_people_domain_model_person_role_rel',
'foreign_table' => 'tx_people_domain_model_role',
'size' => 1,
'minitems' => 0,
'maxitems' => 1,
),
),
),
);
?>
tx_domain_model_role.php:
<?php
return array(
'ctrl' => array(
'title' => 'Rolle',
'label' => 'name',
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'dividers2tabs' => TRUE,
'delete' => 'deleted',
'enablecolumns' => array(
'disabled' => 'hidden',
),
'iconfile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('people') . 'ext_icon.gif'
),
'types' => array(
'1' => array('showitem' => 'name')
),
'columns' => array(
'hidden' => array(
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.hidden',
'config' => array(
'type' => 'check'
)
),
'name' => array(
'label' => 'Bezeichnung',
'config' => array(
'type' => 'input',
'size' => 225,
)
),
// 'people' => array(
// 'label' => 'Personen',
// 'config' => array(
// 'type' => 'inline',
// 'foreign_table' => 'tx_people_domain_model_person_role_rel',
// 'foreign_field' => 'uid_role',
// 'foreign_label' => 'uid_person'
// ) ,
// )
),
);
?>
ext_typoscript_setup.txt:
config.tx_extbase {
persistence {
classes {
Domain\People\Domain\Model\PersonRelation {
mapping {
tableName = tx_people_domain_model_person_role_rel
columns {
uid_local.mapOnProperty = person
uid_foreign.mapOnProperty = role
}
}
}
}
}
}
update debug output:
Domain\People\Domain\Model\Personprototypepersistent entity (uid=1, pid=18)
roles => TYPO3\CMS\Extbase\Persistence\ObjectStorageprototypeobject (3 items)
000000001bb500c600007fe33c9a2f36 => Domain\People\Domain\Model\PersonRelationprototypepersistent entity (uid=1, pid=20)
person => NULL
role => NULL
uid => 1 (integer)
_localizedUid => 1 (integer)modified
_languageUid => NULL
_versionedUid => 1 (integer)modified
pid => 20 (integer)
000000001bb5002400007fe33c9a2f36 => Domain\People\Domain\Model\PersonRelationprototypepersistent entity (uid=2, pid=20)
person => NULL
role => NULL
uid => 2 (integer)
_localizedUid => 2 (integer)modified
_languageUid => NULL
_versionedUid => 2 (integer)modified
pid => 20 (integer)
000000001bb500d100007fe33c9a2f36 => Domain\People\Domain\Model\PersonRelationprototypepersistent entity (uid=3, pid=20)
person => NULL
role => NULL
uid => 3 (integer)
_localizedUid => 3 (integer)modified
_languageUid => NULL
_versionedUid => 3 (integer)modified
pid => 20 (integer)
firstname => 'Max' (3 chars)
lastname => 'Mustermann' (10 chars)
role => 'Rolle' (5 chars)
photo => TYPO3\CMS\Extbase\Domain\Model\FileReferenceprototypepersistent entity (uid=25, pid=18)
description => 'Beschreibungstext' (17 chars)
uid => 1 (integer)
_localizedUid => 1 (integer)modified
_languageUid => NULL
_versionedUid => 1 (integer)modified
pid => 18 (integer)
So the problem is that I need to access those related objects (or the roles of a person) in the frontend.
edit: I think I'm a bit confused about the type of relation I need at all right now. 1 Person can have n roles. I don't want to relate people to roles later on anyways. I just want to create roles and later on assign roles to different people. So it would be a 1:n relation I guess. If that makes it any easier.
The solution was to add the following methods and variables in my Person class:
/**
* roles
*
* #var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Domain\People\Domain\Model\Role>
*/
protected $roles = NULL;
/**
* __construct
*/
public function __construct() {
//Do not remove the next line: It would break the functionality
$this->initStorageObjects();
}
/**
* Initializes all ObjectStorage properties
* Do not modify this method!
* It will be rewritten on each save in the extension builder
* You may modify the constructor of this class instead
*
* #return void
*/
protected function initStorageObjects() {
$this->roles = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
}
/**
* Adds a Role
*
* #param \Domain\People\Domain\Model\Role $role
* #return void
*/
public function addRole(\Domain\People\Domain\Model\Role $role) {
$this->roles->attach($role);
}
/**
* Removes a Role
*
* #param \Domain\People\Domain\Model\Role $roleToRemove The Role to be removed
* #return void
*/
public function removeRole(\Domain\People\Domain\Model\Role $roleToRemove) {
$this->roles->detach($roleToRemove);
}
/**
* Returns the roles
*
* #return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Domain\People\Domain\Model\Role> $roles
*/
public function getRoles() {
return $this->roles;
}
/**
* Sets the roles
*
* #param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Domain\People\Domain\Model\Role> $roles
* #return void
*/
public function setRoles(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $roles) {
$this->roles = $roles;
}

Not able to add object in sql database with extbase / typo3

I building my fist extension in typo3 6.2 with the extentions builder but i'm not able to add any record to the database. I'm reading an XML file and want to put the Ad data in the database. The problem is that notting is happening, no error and no record added in the database. Does anyone have a idee on what i'm doing wrong?
AdsController
class AdsController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
public function insertAdByXML($xml) {
$ad = new \MTR\Mtclnt\Domain\Model\Ads();
$ad->setExtId((int) $xml->ad->ad_id);
$ad->setAdCustId((int) $xml->customer_id);
$this->adsRepository->add($ad);
print_r($ad);
}
}
Output print_r
MTR\Mtclnt\Domain\Model\Ads Object
(
[extId:protected] => 438
[adCustId:protected] => 17605
[adCatId:protected] =>
[adStatus:protected] => 0
[adBrand:protected] =>
[adType:protected] =>
[adYear:protected] =>
[adHours:protected] =>
[adWeight:protected] =>
[adStateNl:protected] =>
[adStateEn:protected] =>
[adStateDe:protected] =>
[adPrice:protected] =>
[adCurrency:protected] =>
[adPriceTypeNl:protected] =>
[adPriceTypeEn:protected] =>
[adPriceTypeDe:protected] =>
[adCusRef:protected] =>
[adMovie:protected] =>
[adSpotlight:protected] =>
[adCarrouselImage:protected] =>
[adOptionsNl:protected] =>
[adOptionsEn:protected] =>
[adOptionsDe:protected] =>
[adDescNl:protected] =>
[adDescEn:protected] =>
[adDescDe:protected] =>
[uid:protected] =>
[_localizedUid:protected] =>
[_languageUid:protected] =>
[_versionedUid:protected] =>
[pid:protected] =>
[_isClone:TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject:private] =>
[_cleanProperties:TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject:private] => Array
(
)
)
AdsRepository
class AdsRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
}
TCA
<?php
if (!defined ('TYPO3_MODE')) {
die ('Access denied.');
}
$GLOBALS['TCA']['tx_mtclnt_domain_model_ads'] = array(
'ctrl' => $GLOBALS['TCA']['tx_mtclnt_domain_model_ads']['ctrl'],
'interface' => array(
'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, ext_id, ad_cust_id, ad_cat_id, ad_status, ad_brand, ad_type, ad_year, ad_hours, ad_weight, ad_state_nl, ad_state_en, ad_state_de, ad_price, ad_currency, ad_price_type_nl, ad_price_type_en, ad_price_type_de, ad_cus_ref, ad_movie, ad_spotlight, ad_carrousel_image, ad_options_nl, ad_options_en, ad_options_de, ad_desc_nl, ad_desc_en, ad_desc_de',
),
'types' => array(
'1' => array('showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, hidden;;1, ext_id, ad_cust_id, ad_cat_id, ad_status, ad_brand, ad_type, ad_year, ad_hours, ad_weight, ad_state_nl, ad_state_en, ad_state_de, ad_price, ad_currency, ad_price_type_nl, ad_price_type_en, ad_price_type_de, ad_cus_ref, ad_movie, ad_spotlight, ad_carrousel_image, ad_options_nl, ad_options_en, ad_options_de, ad_desc_nl, ad_desc_en, ad_desc_de, --div--;LLL:EXT:cms/locallang_ttc.xlf:tabs.access, starttime, endtime'),
),
'palettes' => array(
'1' => array('showitem' => ''),
),
'columns' => array(
'sys_language_uid' => array(
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.language',
'config' => array(
'type' => 'select',
'foreign_table' => 'sys_language',
'foreign_table_where' => 'ORDER BY sys_language.title',
'items' => array(
array('LLL:EXT:lang/locallang_general.xlf:LGL.allLanguages', -1),
array('LLL:EXT:lang/locallang_general.xlf:LGL.default_value', 0)
),
),
),
'l10n_parent' => array(
'displayCond' => 'FIELD:sys_language_uid:>:0',
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.l18n_parent',
'config' => array(
'type' => 'select',
'items' => array(
array('', 0),
),
'foreign_table' => 'tx_mtclnt_domain_model_ads',
'foreign_table_where' => 'AND tx_mtclnt_domain_model_ads.pid=###CURRENT_PID### AND tx_mtclnt_domain_model_ads.sys_language_uid IN (-1,0)',
),
),
'l10n_diffsource' => array(
'config' => array(
'type' => 'passthrough',
),
),
't3ver_label' => array(
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.versionLabel',
'config' => array(
'type' => 'input',
'size' => 30,
'max' => 255,
)
),
'hidden' => array(
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.hidden',
'config' => array(
'type' => 'check',
),
),
'starttime' => array(
'exclude' => 1,
'l10n_mode' => 'mergeIfNotBlank',
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.starttime',
'config' => array(
'type' => 'input',
'size' => 13,
'max' => 20,
'eval' => 'datetime',
'checkbox' => 0,
'default' => 0,
'range' => array(
'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y'))
),
),
),
'endtime' => array(
'exclude' => 1,
'l10n_mode' => 'mergeIfNotBlank',
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.endtime',
'config' => array(
'type' => 'input',
'size' => 13,
'max' => 20,
'eval' => 'datetime',
'checkbox' => 0,
'default' => 0,
'range' => array(
'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y'))
),
),
),
'ext_id' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ext_id',
'config' => array(
'type' => 'input',
'size' => 4,
'eval' => 'int'
)
),
'ad_cust_id' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_cust_id',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_cat_id' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_cat_id',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_status' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_status',
'config' => array(
'type' => 'input',
'size' => 4,
'eval' => 'int'
)
),
'ad_brand' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_brand',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_type' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_type',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_year' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_year',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_hours' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_hours',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_weight' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_weight',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_state_nl' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_state_nl',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_state_en' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_state_en',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_state_de' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_state_de',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_price' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_price',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_currency' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_currency',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_price_type_nl' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_price_type_nl',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_price_type_en' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_price_type_en',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_price_type_de' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_price_type_de',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_cus_ref' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_cus_ref',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_movie' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_movie',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_spotlight' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_spotlight',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_carrousel_image' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_carrousel_image',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_options_nl' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_options_nl',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_options_en' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_options_en',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_options_de' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_options_de',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_desc_nl' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_desc_nl',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_desc_en' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_desc_en',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
'ad_desc_de' => array(
'exclude' => 1,
'label' => 'LLL:EXT:mtclnt/Resources/Private/Language/locallang_db.xlf:tx_mtclnt_domain_model_ads.ad_desc_de',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
),
);
Adsmodel
class Ads extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
/**
* extId
*
* #var integer
*/
protected $extId = 0;
/**
* adCustId
*
* #var string
*/
protected $adCustId = '';
/**
* adCatId
*
* #var string
*/
protected $adCatId = '';
/**
* adStatus
*
* #var integer
*/
protected $adStatus = 0;
/**
* adBrand
*
* #var string
*/
protected $adBrand = '';
/**
* adType
*
* #var string
*/
protected $adType = '';
/**
* adYear
*
* #var string
*/
protected $adYear = '';
/**
* adHours
*
* #var string
*/
protected $adHours = '';
/**
* adWeight
*
* #var string
*/
protected $adWeight = '';
/**
* adStateNl
*
* #var string
*/
protected $adStateNl = '';
/**
* adStateEn
*
* #var string
*/
protected $adStateEn = '';
/**
* adStateDe
*
* #var string
*/
protected $adStateDe = '';
/**
* adPrice
*
* #var string
*/
protected $adPrice = '';
/**
* adCurrency
*
* #var string
*/
protected $adCurrency = '';
/**
* adPriceTypeNl
*
* #var string
*/
protected $adPriceTypeNl = '';
/**
* adPriceTypeEn
*
* #var string
*/
protected $adPriceTypeEn = '';
/**
* adPriceTypeDe
*
* #var string
*/
protected $adPriceTypeDe = '';
/**
* adCusRef
*
* #var string
*/
protected $adCusRef = '';
/**
* adMovie
*
* #var string
*/
protected $adMovie = '';
/**
* adSpotlight
*
* #var string
*/
protected $adSpotlight = '';
/**
* adCarrouselImage
*
* #var string
*/
protected $adCarrouselImage = '';
/**
* adOptionsNl
*
* #var string
*/
protected $adOptionsNl = '';
/**
* adOptionsEn
*
* #var string
*/
protected $adOptionsEn = '';
/**
* adOptionsDe
*
* #var string
*/
protected $adOptionsDe = '';
/**
* adDescNl
*
* #var string
*/
protected $adDescNl = '';
/**
* adDescEn
*
* #var string
*/
protected $adDescEn = '';
/**
* adDescDe
*
* #var string
*/
protected $adDescDe = '';
/**
* Returns the adBrand
*
* #return string $adBrand
*/
public function getAdBrand() {
return $this->adBrand;
}
/**
* Sets the adBrand
*
* #param string $adBrand
* #return void
*/
public function setAdBrand($adBrand) {
$this->adBrand = $adBrand;
}
/**
* Returns the adType
*
* #return string adType
*/
public function getAdType() {
return $this->adType;
}
/**
* Sets the adType
*
* #param string $adType
* #return string adType
*/
public function setAdType($adType) {
$this->adType = $adType;
}
/**
* Returns the extId
*
* #return integer $extId
*/
public function getExtId() {
return $this->extId;
}
/**
* Sets the extId
*
* #param integer $extId
* #return void
*/
public function setExtId($extId) {
$this->extId = $extId;
}
/**
* Returns the adStatus
*
* #return integer $adStatus
*/
public function getAdStatus() {
return $this->adStatus;
}
/**
* Sets the adStatus
*
* #param integer $adStatus
* #return void
*/
public function setAdStatus($adStatus) {
$this->adStatus = $adStatus;
}
/**
* Returns the adYear
*
* #return string $adYear
*/
public function getAdYear() {
return $this->adYear;
}
/**
* Sets the adYear
*
* #param string $adYear
* #return void
*/
public function setAdYear($adYear) {
$this->adYear = $adYear;
}
/**
* Returns the adHours
*
* #return string $adHours
*/
public function getAdHours() {
return $this->adHours;
}
/**
* Sets the adHours
*
* #param string $adHours
* #return void
*/
public function setAdHours($adHours) {
$this->adHours = $adHours;
}
/**
* Returns the adWeight
*
* #return string $adWeight
*/
public function getAdWeight() {
return $this->adWeight;
}
/**
* Sets the adWeight
*
* #param string $adWeight
* #return void
*/
public function setAdWeight($adWeight) {
$this->adWeight = $adWeight;
}
/**
* Returns the adStateNl
*
* #return string $adStateNl
*/
public function getAdStateNl() {
return $this->adStateNl;
}
/**
* Sets the adStateNl
*
* #param string $adStateNl
* #return void
*/
public function setAdStateNl($adStateNl) {
$this->adStateNl = $adStateNl;
}
/**
* Returns the adStateEn
*
* #return string $adStateEn
*/
public function getAdStateEn() {
return $this->adStateEn;
}
/**
* Sets the adStateEn
*
* #param string $adStateEn
* #return void
*/
public function setAdStateEn($adStateEn) {
$this->adStateEn = $adStateEn;
}
/**
* Returns the adStateDe
*
* #return string $adStateDe
*/
public function getAdStateDe() {
return $this->adStateDe;
}
/**
* Sets the adStateDe
*
* #param string $adStateDe
* #return void
*/
public function setAdStateDe($adStateDe) {
$this->adStateDe = $adStateDe;
}
/**
* Returns the adPrice
*
* #return string $adPrice
*/
public function getAdPrice() {
return $this->adPrice;
}
/**
* Sets the adPrice
*
* #param string $adPrice
* #return void
*/
public function setAdPrice($adPrice) {
$this->adPrice = $adPrice;
}
/**
* Returns the adCurrency
*
* #return string $adCurrency
*/
public function getAdCurrency() {
return $this->adCurrency;
}
/**
* Sets the adCurrency
*
* #param string $adCurrency
* #return void
*/
public function setAdCurrency($adCurrency) {
$this->adCurrency = $adCurrency;
}
/**
* Returns the adPriceTypeNl
*
* #return string $adPriceTypeNl
*/
public function getAdPriceTypeNl() {
return $this->adPriceTypeNl;
}
/**
* Sets the adPriceTypeNl
*
* #param string $adPriceTypeNl
* #return void
*/
public function setAdPriceTypeNl($adPriceTypeNl) {
$this->adPriceTypeNl = $adPriceTypeNl;
}
/**
* Returns the adPriceTypeEn
*
* #return string $adPriceTypeEn
*/
public function getAdPriceTypeEn() {
return $this->adPriceTypeEn;
}
/**
* Sets the adPriceTypeEn
*
* #param string $adPriceTypeEn
* #return void
*/
public function setAdPriceTypeEn($adPriceTypeEn) {
$this->adPriceTypeEn = $adPriceTypeEn;
}
/**
* Returns the adPriceTypeDe
*
* #return string $adPriceTypeDe
*/
public function getAdPriceTypeDe() {
return $this->adPriceTypeDe;
}
/**
* Sets the adPriceTypeDe
*
* #param string $adPriceTypeDe
* #return void
*/
public function setAdPriceTypeDe($adPriceTypeDe) {
$this->adPriceTypeDe = $adPriceTypeDe;
}
/**
* Returns the adCusRef
*
* #return string $adCusRef
*/
public function getAdCusRef() {
return $this->adCusRef;
}
/**
* Sets the adCusRef
*
* #param string $adCusRef
* #return void
*/
public function setAdCusRef($adCusRef) {
$this->adCusRef = $adCusRef;
}
/**
* Returns the adMovie
*
* #return string $adMovie
*/
public function getAdMovie() {
return $this->adMovie;
}
/**
* Sets the adMovie
*
* #param string $adMovie
* #return void
*/
public function setAdMovie($adMovie) {
$this->adMovie = $adMovie;
}
/**
* Returns the adSpotlight
*
* #return string $adSpotlight
*/
public function getAdSpotlight() {
return $this->adSpotlight;
}
/**
* Sets the adSpotlight
*
* #param string $adSpotlight
* #return void
*/
public function setAdSpotlight($adSpotlight) {
$this->adSpotlight = $adSpotlight;
}
/**
* Returns the adCarrousselImage
*
* #return boolean $adCarrousselImage
*/
public function getAdCarrousselImage() {
return $this->adCarrousselImage;
}
/**
* Sets the adCarrousselImage
*
* #param boolean $adCarrousselImage
* #return void
*/
public function setAdCarrousselImage($adCarrousselImage) {
$this->adCarrousselImage = $adCarrousselImage;
}
/**
* Returns the boolean state of adCarrousselImage
*
* #return boolean
*/
public function isAdCarrousselImage() {
return $this->adCarrousselImage;
}
/**
* Returns the adOptionsNl
*
* #return string $adOptionsNl
*/
public function getAdOptionsNl() {
return $this->adOptionsNl;
}
/**
* Sets the adOptionsNl
*
* #param string $adOptionsNl
* #return void
*/
public function setAdOptionsNl($adOptionsNl) {
$this->adOptionsNl = $adOptionsNl;
}
/**
* Returns the adOptionsEn
*
* #return string $adOptionsEn
*/
public function getAdOptionsEn() {
return $this->adOptionsEn;
}
/**
* Sets the adOptionsEn
*
* #param string $adOptionsEn
* #return void
*/
public function setAdOptionsEn($adOptionsEn) {
$this->adOptionsEn = $adOptionsEn;
}
/**
* Returns the adOptionsDe
*
* #return string $adOptionsDe
*/
public function getAdOptionsDe() {
return $this->adOptionsDe;
}
/**
* Sets the adOptionsDe
*
* #param string $adOptionsDe
* #return void
*/
public function setAdOptionsDe($adOptionsDe) {
$this->adOptionsDe = $adOptionsDe;
}
/**
* Returns the adDescNl
*
* #return string $adDescNl
*/
public function getAdDescNl() {
return $this->adDescNl;
}
/**
* Sets the adDescNl
*
* #param string $adDescNl
* #return void
*/
public function setAdDescNl($adDescNl) {
$this->adDescNl = $adDescNl;
}
/**
* Returns the adDescEn
*
* #return string $adDescEn
*/
public function getAdDescEn() {
return $this->adDescEn;
}
/**
* Sets the adDescEn
*
* #param string $adDescEn
* #return void
*/
public function setAdDescEn($adDescEn) {
$this->adDescEn = $adDescEn;
}
/**
* Returns the adDescDe
*
* #return string $adDescDe
*/
public function getAdDescDe() {
return $this->adDescDe;
}
/**
* Sets the adDescDe
*
* #param string $adDescDe
* #return void
*/
public function setAdDescDe($adDescDe) {
$this->adDescDe = $adDescDe;
}
/**
* Returns the adCatId
*
* #return string $adCatId
*/
public function getAdCatId() {
return $this->adCatId;
}
/**
* Sets the adCatId
*
* #param string $adCatId
* #return void
*/
public function setAdCatId($adCatId) {
$this->adCatId = $adCatId;
}
/**
* Returns the adCustId
*
* #return string $adCustId
*/
public function getAdCustId() {
return $this->adCustId;
}
/**
* Sets the adCustId
*
* #param string $adCustId
* #return void
*/
public function setAdCustId($adCustId) {
$this->adCustId = $adCustId;
}
/**
* __construct
*/
public function __construct() {
//Do not remove the next line: It would break the functionality
$this->initStorageObjects();
}
/**
* Initializes all ObjectStorage properties
* Do not modify this method!
* It will be rewritten on each save in the extension builder
* You may modify the constructor of this class instead
*
* #return void
*/
protected function initStorageObjects() {
}
/**
* Returns the adUsed
*
* #return string $adUsed
*/
public function getAdUsed() {
return $this->adUsed;
}
/**
* Sets the adUsed
*
* #param string $adUsed
* #return void
*/
public function setAdUsed($adUsed) {
$this->adUsed = $adUsed;
}
}

How to validate my form in Zend Framework 2 and Doctrine?

so i have some entities and i want to validate my forms, i use Zend Framework 2 and Doctrine Orm, Update Thanks to Notuser : now i get this error :
Fatal error: Call to undefined method Zend\ServiceManager\ServiceManager::initForm() in C:\wamp2\www\test\module\Application\src\Application\Controller\BlogController.php
this is my model.config.php :
'doctrine' => array(
'driver' => array(
'application_entities' => array(
'class' =>'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(__DIR__ . '/../src/Application/Entity')
),
'application_forms' => array(
'class' =>'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(__DIR__ . '/../src/Application/Form')
),
'application_inputs_filters' => array(
'class' =>'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(__DIR__ . '/../src/Application/InputFilter')
),
'orm_default' => array(
'drivers' => array(
'Application\Entity' => 'application_entities',
'Application\Form' => 'application_forms',
'Application\InputFilter' => 'application_inputs_filters'
)
)
)
),
and this my controller :
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Application\Entity\Article;
use Application\Entity\Image;
use Application\Form\ArticleForm;
class BlogController extends AbstractActionController
{
protected $_objectManager;
public function addAction()
{
$form = $this->getServiceLocator('Application\Form\ArticleForm');
$form->initForm();
$request = $this->getRequest();
$form->setData($request->getPost());
$article = new Article();
if ($this->zfcUserAuthentication()->hasIdentity()) {
if ($form->isValid())
{
$file = $this->params()->fromFiles('url');
$adapter = new \Zend\File\Transfer\Adapter\Http();
$adapter->setDestination('public/upload');
if($adapter->receive($file['name'])){
$article->setTitle($this->getRequest()->getPost('title'));
$article->setDate(new \DateTime($this->getRequest()->getPost('date')));
$article->setContent($this->getRequest()->getPost('content'));
$article->setPublication($this->getRequest()->getPost('publication'));
$image = new Image();
$image->setUrl($file['name']);
$image->setAlt($this->getRequest()->getPost('alt'));
$article->setImage($image);
$this->getObjectManager()->persist($article);
$this->getObjectManager()->flush();
$newId = $article->getId();
return $this->redirect()->toRoute('blog');
}
}
}
else
{
return $this->redirect()->toRoute('user');
}
return new ViewModel(array('article' => $article));
}
And this is my ArticleForm :
class ArticleForm extends Form {
public function __construct()
{
parent::__construct('UserEntry');
$this->setAttribute('method', 'post');
$this->setAttribute('enctype', 'multipart/form-data');
$this->setAttribute('class', 'contact_form');
}
/**
*
*/
public function initForm()
{
$this->addFormFields(); //function where we added all fields
$articleInputFilter = new ArticleInputFilter();
$this->setInputFilter($articleInputFilter->getInputFilter()); //Asign input Filter to form
}
/**
*
*/
protected function addFormFields()
{
$this->addSubmit();
$this->addTitle();
$this->addContent();
$this->addDate();
$this->addPublication();
$this->addImage();
}
/**
*
*/
protected function addTitle()
{
$this->add(array(
'name' => 'title',
'attributes' => array(
'type' => 'text',
),
'options' => array(
'label' => _('Title')
),
));
}
/**
*
*/
protected function addContent()
{
$this->add(array(
'name' => 'content',
'attributes' => array(
'type' => 'text',
),
'options' => array(
'label' => _('Content')
),
));
}
/**
*
*/
protected function addDate()
{
$this->add(array(
'name' => 'date',
'attributes' => array(
'type' => 'date',
),
'options' => array(
'label' => _('Date'),
'id' => 'datepicker',
),
));
}
/**
*
*/
protected function addPublication()
{
$this->add(array(
'name' => 'publication',
'attributes' => array(
'type' => 'checkbox',
),
'options' => array(
'label' => _('Publication'),
'use_hidden_element' => true,
'checked_value' => 1,
'unchecked_value' => 'no',
),
));
}
/**
*
*/
protected function addImage()
{
$this->add(array(
'name' => 'Image',
'attributes' => array(
'type' => new ImageForm(),
),
'options' => array(
'label' => _('Image')
),
));
}
/**
*
*/
protected function addSubmit()
{
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => _('Add'),
'class' => 'submit',
),
));
}
}
Finally this is my ArticleInputFilter :
class ArticleInputFilter extends InputFilter implements InputFilterAwareInterface
{
/**
* #var string
*/
public $title;
/**
* #var int
*/
public $image;
/**
* #var string
*/
public $content;
/**
* #var Date
*/
public $date;
/**
* #var Boolean
*/
public $publication;
/**
* #param $data
*/
public function exchangeArray($data)
{
$this->title = (isset($data['title'])) ? $data['title'] : $this->title;
$this->image = (isset($data['image'])) ? $data['image'] : $this->image;
$this->content = (isset($data['content'])) ? $data['content'] : $this->content;
$this->publication = (isset($data['publication'])) ? $data['publication'] : $this->publication;
$this->date = (isset($data['date'])) ? $data['date'] : $this->date;
}
/**
* #param InputFilterInterface $inputFilter
* #return void|InputFilterAwareInterface
* #throws \Exception
*/
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new \Exception("Not used");
}
/**
* #return InputFilter|InputFilterInterface
*/
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'title',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 6,
'max' => 100,
),
),
),
)));
$inputFilter->add($factory->createInput(array(
'name' => 'content',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 10,
),
),
),
)));
$inputFilter->add($factory->createInput(array(
'name' => 'publication',
'required' => false,
)));
$inputFilter->add($factory->createInput(array(
'name' => 'date',
'required' => true,
)));
$inputFilter->add($factory->createInput(array(
'name' => 'image',
'required' => true,
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
}
That it i write my hole code except my ImageForm and ImageInputFilter, So please if someone has any idea how to do that i will be very appreciative ;)
In controller
$form = $this->getServiceLocator('Application\Form\BlogForm");//don't forger to add Application\Form\BlogForm to module.config.php and check your namespace
$form->initForm();//explained further
/** #var \Zend\Http\Request $request */
$request = $this->getRequest();//whole request fo #var for further using
if ($request->isPost()) { //there is something in post
$form->setData($request->getPost()); //data from post is added for further validation
if ($form->isValid()) { //Form is Valid lets save form
$files = $request->getFiles()->toArray(); //array witch files use var_dump($files);die; to show structure
$article = new Article();
$article->setTitle($request->getPost('title'));
...
if(!empty($files)&&$files['image']['error']==0) {
$article->setImage($functionToCreateImageEntityFromFile(($files['image']));
}
...
$this->getObjectManager()->persist($article);
$this->getObjectManager()->flush();
$newId = $article->getId();
return $this->redirect()->toRoute('blog');
}
//form is not valid so you can display form with Errors
} //there is no post so you can display clean form
Next let's take form:
(it's my proposal)
namespace Application\Form; //check your namespace
use Zend\Form\Form;
use Application\InputFilter\BlogInputFilter; //check your namespace
class BlogForm extends Form {
public function __construct()
{
parent::__construct('UserEntry');
$this->setAttribute('method', 'post');
$this->setAttribute('enctype', 'multipart/form-data');
}
/**
*
*/
public function initForm()
{
$this->addFormFields(); //function where we added all fields
$blogInputFilter = new BlogInputFilter(); //Input Filter for Validation
$this->setInputFilter($BlogInputFilter->getInputFilter()); //Asign input Filter to form
}
/**
*
*/
protected function addFormFields()
{
$this->addSubmit();
$this->addTitle();
$this->addImage();
...//add more here
}
/**
*
*/
protected function addTitle()
{
$this->add(array(
'name' => 'title',
'attributes' => array(
'type' => 'text',
'id' => 'title',
'class' => 'text'
),
'options' => array(
'label' => _('Title') //it's only for multilang you can put here any string
),
));
}
/**
*
*/
protected function addImage()
{
$this->add(array(
'name' => 'image',
'attributes' => array(
'type' => 'file',
'id' => 'image'
),
'options' => array(
'label' => _('Image'),
),
));
}
/**
*
*/
protected function addSubmit()
{
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => _('Save'),
'class' => 're',
),
));
}
}
Now its Time for InputFilter
namespace Application\InputFilter;//check your namespace
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
class BlogInputFilter implements InputFilterAwareInterface
{
/**
* #var int
*/
public $title;
/**
* #var string
*/
public $image;
//add all fields
/**
* #param $data
*/
public function exchangeArray($data)
{
$this->title = (isset($data['title'])) ? $data['title'] : $this->title;
$this->image = (isset($data['image'])) ? $data['image'] : $this->image;
//add fields
}
/**
* #param InputFilterInterface $inputFilter
* #return void|InputFilterAwareInterface
* #throws \Exception
*/
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new \Exception("Not used");
}
/**
* #return InputFilter|InputFilterInterface
*/
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'title',
'required' => true,//required field
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 100,//limit from 1 to 100 chars
),
),
),
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
}
to read:
Forms: http://framework.zend.com/manual/2.0/en/modules/zend.form.quick-start.html#factory-backed-form-extension
ImputFilter: http://framework.zend.com/manual/2.0/en/modules/zend.input-filter.intro.html
File upload: Can't find good tutorial
module.config.php should have key like this:
'service_manager' => array(
'invokables' => array(
'Application\Form\ArticleForm' => 'Application\Form\ArticleForm',
),
),
There is no need to add Application\Form\ArticleForm to use becouse you use ServiceLocator
This is your problem:
$form = $this->getServiceLocator('Application\Form\ArticleForm');
$form->initForm();
It should be:
$form = $this->getServiceLocator()->get('Application\Form\ArticleForm');
$form->initForm();
The way you have written it, the bracket contents are ignored and it becomes:
$form = $this->getServiceLocator()
which is why you get an "undefined method: ServiceManager::initForm()" error when you call initForm().