Custom WooCommerce payment gateway not showing up - woocommerce

I created a custom WooCommerce 3.0 payment gateway to process credit cards:
add_action('plugins_loaded', 'wc_custom_gateway_init');
function wc_custom_gateway_init()
{
/**
* custom Payment Gateway
*
* #class WC_Gateway_custom
* #extends WC_Payment_Gateway
* #version 1.0.0
* #package WooCommerce/Classes/Payment
*/
class WC_Gateway_custom extends WC_Payment_Gateway
{
public function __construct()
{
$this->id = 'custom';
$this->icon = null;
$this->has_fields = true;
$this->method_title = 'custom';
$this->method_description = 'custom payment gateway';
$this->init_form_fields();
$this->init_settings();
}
/**
* Initialize Gateway Settings Form Fields
*/
public function init_form_fields()
{
$this->form_fields = [
'enabled' => [
'title' => __('Enable/Disable', 'wc-gateway-custom'),
'type' => 'checkbox',
'label' => __('Enable custom Payment', 'wc-gateway-custom'),
'default' => 'yes'
],
// This controls the title for the payment method the customer sees during checkout.
'title' => [
'title' => __('Title', 'wc-gateway-custom'),
'type' => 'text',
'description' => __('Credit Card', 'wc-gateway-custom'),
'default' => __('Credit Card', 'wc-gateway-custom'),
'desc_tip' => true,
],
// Payment method description that the customer will see on your checkout.
'description' => [
'title' => __('Description', 'wc-gateway-custom'),
'type' => 'textarea',
'description' => __('Credit Card', 'wc-gateway-custom'),
'default' => __('Credit Card', 'wc-gateway-custom'),
'desc_tip' => true,
],
// Instructions that will be added to the thank you page and emails.
'instructions' => [
'title' => __('Instructions', 'wc-gateway-custom'),
'type' => 'textarea',
'description' => __('', 'wc-gateway-custom'),
'default' => '',
'desc_tip' => true,
],
];
}
/**
* #param int $order_id
*
* #return array|null
*/
public function process_payment($order_id)
{
$order = wc_get_order($order_id);
// ... API call and various validation logic...
// Remove cart
WC()->cart->empty_cart();
return [
'result' => 'success',
'redirect' => $this->get_return_url($order)
];
}
}
/**
* Add the gateway to the WC list.
*
* #param array $gateways
*
* #return array
*/
function wc_custom_add_to_gateways($gateways)
{
$gateways[] = 'WC_Gateway_custom';
return $gateways;
}
add_filter('woocommerce_payment_gateways', 'wc_custom_add_to_gateways');
}
However, the custom gateway never shows up in the list of gateways on the WC settings page.
What step am I missing here?

Related

Laminas / Zf3 - getting parameters from Fieldset but it return null values

I was following the instructions of #crash and I get the value of my parameter passed in my fieldset. But sometimes it returns a null value. Here are my complete code
My RapportEffetForm :
<?php
/**
* #module Commun
* #subpackage Form\Admin
* #author Samuel NANGUI <nanguisamuel#gmail.com>
* #copyright Copyright (c) 2021 Nslabs
*/
namespace Commun\Form\Modules\Application;
use Commun\Form\Modules\Application\Fieldset\RapportEffetFieldset;
use Commun\Form\CommunForm;
class RapportEffetForm extends CommunForm
{
private $parameters;
public function __construct($params)
{
$this->parameters=$params;
parent::__construct('RapportEffetForm',$this->parameters,[]);
}
public function init() {
$myFieldset = $this->getFormFactory()->getFormElementManager()->get(RapportEffetFieldset::class, ['params' => $this->parameters]);
$this->setName('RapportEffetForm');
$this->setAttribute('class', 'form-saisie');
//$this->addFieldset(RapportEffetFieldset::class,['use_as_base_fieldset' => true]);
$this->addFieldsetWithParameters($myFieldset,['use_as_base_fieldset' => true]);
$this->addSubmitButton('next', 'Poursuivre', 'next', 'btn btn-vert w-100');
$this->addSubmitButton('previous', 'Retour', 'previous', 'btn btn-rouge w-100');
}
}
My RapportEffetFormFactory :
<?php
/**
* #module Commun
* #subpackage Form
* #author Samuel NANGUI <nanguisamuel#gmail.com>
* #copyright Copyright (c) 2020 Nslabs
*/
namespace Commun\Factory\Form;
use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Commun\Form\Modules\Application\RapportEffetForm;
class RapportEffetFormFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$params = $options['id'] ?? [];
unset($options['id']);
return new RapportEffetForm($params);
}
}
My RapportEffetFieldset :
<?php
/**
* #module Commun
* #subpackage Form\Admin
* #author Samuel NANGUI <nanguisamuel#gmail.com>
* #copyright Copyright (c) 2020 Nslabs
*/
namespace Commun\Form\Modules\Application\Fieldset;
use Commun\Model\Entity\Supervision;
use Laminas\InputFilter\InputFilterProviderInterface;
use Laminas\Hydrator\ReflectionHydrator;
use Commun\Form\Modules\Application\Fieldset\EffetRapportFieldset;
use Commun\Form\CommunFormFieldset;
class RapportEffetFieldset extends CommunFormFieldset implements InputFilterProviderInterface
{
private $mapper;
private $params;
public function __construct($mappers=[],$params=[], $options = [])
{
$this->mapper = $mappers;
$this->params = $params;
parent::__construct($this->mapper,'RapportEffetForm',$options);
$this->setHydrator(new ReflectionHydrator());
$this->setObject(new Supervision());
$this->setLabel('RapportEffetFieldset');
}
public function init() {
parent::init();
$myFieldset = $this->getFormFactory()->getFormElementManager()->get(EffetRapportFieldset::class, ['params' => $this->params]);
$this->addCollection('effets','', get_class(new $myFieldset()),1,[],'__index__',FALSE,FALSE);
$optionsNotation = $this->mapper['notations']->getOptions('idRefNotation','libelle','Sélectionner',null,['ordre']);
$this->addSelect('notationEffetPresent', 'Notation du présent rapport',$optionsNotation,['class' => 'form-control'],'champ-requis');
$this->addSelect('notationEffetPrecedent', 'Notation du rapport précédent',$optionsNotation,['class' => 'form-control champ-affiche', 'placeholder' => 'Choisir']);
$this->addTextarea('JustifNotationEffet', 'Justification', NULL, ['class' => 'form-control','rows' => 5]);
}
/**
* #return array
*/
public function getInputFilterSpecification()
{
return [
];
}
}
My RapportEffetFieldsetFactory :
<?php
/**
* #module Commun
* #subpackage Form
* #author Samuel NANGUI <nanguisamuel#gmail.com>
* #copyright Copyright (c) 2020 Nslabs
*/
namespace Commun\Factory\Form\Fieldset;
use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Commun\Form\Modules\Application\Fieldset\RapportEffetFieldset;
class RapportEffetFieldsetFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$params = $options['params'] ?? [];
unset($options['params']);
$mappers = ['notations' => $container->get('TREFNOTATION')];
return new RapportEffetFieldset($mappers,$params,$options);
}
}
My EffetRapportFieldset :
<?php
/**
* #module Commun
* #subpackage Form\Admin
* #author Samuel NANGUI <nanguisamuel#gmail.com>
* #copyright Copyright (c) 2020 Nslabs
*/
namespace Commun\Form\Modules\Application\Fieldset;
use Commun\Model\Entity\EffetProjet;
use Laminas\InputFilter\InputFilterProviderInterface;
use Laminas\Hydrator\ReflectionHydrator;
use Laminas\Filter\StripTags;
use Laminas\Filter\StringTrim;
use Commun\Form\CommunFormFieldset;
class EffetRapportFieldset extends CommunFormFieldset implements InputFilterProviderInterface
{
private $mapper;
private $inputFilter;
private $params;
public function __construct($mappers=[],$params=[], $options = [])
{
$this->mapper = $mappers;
$this->params = $params;
parent::__construct($this->mapper,'EffetRapportForm',$options);
$this->setHydrator(new ReflectionHydrator());
$this->setObject(new EffetProjet());
}
public function init() {
parent::init();
var_dump($this->params);
//die;
$idProjet = $this->params['id']; // I retrieve my param here like this. But I get this warning <<Notice: Undefined index: id in EffetRapportFieldset.php on line 45>>
$optionsEffetCadreLogique = $this->mapper['effetProjet']->getOptions('idEffetProjet','libelleEffet','Sélectionner',['idProjet' => $idProjet],['libelleEffet']);
$this->addSelect('idEffetProjet', 'Intitule de l\'effet',$optionsEffetCadreLogique,['class' => 'form-control champ-affiche'],'champ-requis');
$this->addText('valeurReference','Valeur de référence (a)',NULL,['class' => 'form-control champ_decimal champ-affiche'],'champ-requis');
$this->addText('valeurRecente','Valeur la plus récente (b)',NULL,['class' => 'form-control champ_decimal'],'champ-requis');
$this->addText('valeurCible','Cible finale (c)',NULL,['class' => 'form-control champ_decimal champ-calcule'],'champ-requis');
$this->addText('progresRealisation','Progrès vers la réalisation de la cible (% de réalisation) (d=b/c)',NULL,['class' => 'form-control champ_decimal champ-affiche'],'champ-requis');
$this->addTextarea('evaluation', 'Évaluation', NULL, ['class' => 'form-control','rows' => 3]);
}
/**
* #return array
*/
public function getInputFilterSpecification()
{
return [
];
}
}
My EffetRapportFieldsetFactory :
<?php
/**
* #module Commun
* #subpackage Form
* #author Samuel NANGUI <nanguisamuel#gmail.com>
* #copyright Copyright (c) 2020 Nslabs
*/
namespace Commun\Factory\Form\Fieldset;
use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Commun\Form\Modules\Application\Fieldset\EffetRapportFieldset;
class EffetRapportFieldsetFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$params = $options['params'] ?? [];
unset($options['params']);
$mappers = ['effetProjet' => $container->get('TEFFETPROJET')];
return new EffetRapportFieldset($mappers,$params,$options);
}
}
My CommunForm class here :
<?php
/**
* #module Commun
* #subpackage Form
* #author Samuel NANGUI <nanguisamuel#gmail.com>
* #copyright Copyright (c) 2020 Nslabs
*/
namespace Commun\Form;
use Laminas\Form\Form;
use Laminas\Hydrator\ClassMethodsHydrator;
use Laminas\InputFilter\InputFilter;
use Laminas\Form\Element\Select;
use Laminas\Form\Element\Hidden;
class CommunForm extends Form
{
protected $mapper;
public $params;
public function __construct($formName=null,$params=[],$mapper=[]) {
parent::__construct($formName);
$this->mapper = $mapper;
$this->params = $params;
$this->setHydrator(new ClassMethodsHydrator(false));
$this->setInputFilter(new InputFilter());
$this->setAttribute('class', 'form-horizontal');
//$this->setOption('params', $params);
}
public function populateSelect(\Laminas\Form\Element\Select $selectName,$optionValues=[]){
$selectName->setValueOptions($optionValues);
}
public function addFieldset($fieldset,$options=[]){
$this->add([
'type' => $fieldset,
'options' => $options,
]);
}
public function addFieldsetWithParameters($fieldset,$options=[]){
$this->add([
'type' => get_class(new $fieldset()),
'options' => $options,
]);
}
public function addSubmitButton($name,$label,$id='',$className=''){
$this->add([
'name' => $name,
'type' => 'submit',
'attributes' => [
'value' => $label,
'id' => $id,
'class' => $className,
]
]);
}
public function addSelect($name,$label){
$this->add([
'name' => $name,
'type' => Select::class,
'options' => [
'label' => $label,
'value_options' => [
'0' => 'French',
'1' => 'English',
'2' => 'Japanese',
'3' => 'Chinese',
],
],
]);
}
public function addFile($name,$label,$id='',$attributes=[],$labelClass=''){
$this->add([
'name' => $name,
'type' => 'file',
'options' => [
'label' => $label,
'id' => $id,
'label_attributes' => [
'class' => $labelClass
],
],
'attributes' => $attributes,
]);
}
public function addHiddenElement($name,$attributes=[]){
$this->add([
'name' => $name,
'type' => Hidden::class,
'attributes' => $attributes,
]);
}
public function addText($name,$label,$id='',$attributes=[],$labelClass=''){
$this->add([
'name' => $name,
'type' => 'text',
'options' => [
'label' => $label,
'id' => $id,
'label_attributes' => [
'class' => $labelClass
],
],
'attributes' => $attributes,
]);
}
}
and my CommunFieldset :
<?php
/**
* #module Commun
* #subpackage Form
* #author Samuel NANGUI <nanguisamuel#gmail.com>
* #copyright Copyright (c) 2021 Nslabs
*/
namespace Commun\Form;
use Laminas\Form\Element\Select;
use Laminas\Form\Fieldset;
use Laminas\Form\Element\Checkbox;
use Laminas\Form\Element\MultiCheckbox;
use Laminas\Form\Element\Button;
use Laminas\Form\Element\Hidden;
class CommunFormFieldset extends Fieldset
{
/**
* Shortcut for adding an input type text element
* #param string $name name of the item
* #param string $label label of the item
* #param string $id unique HTML id of the item
* #param array $attributes array of attributes to apply to the item
*/
//public $additionnalParams;
private $mapper;
public function __construct($mapper=[],$name=null,$options = []) {
//$this->additionnalParams = $options;
$this->mapper = $mapper;
parent::__construct($name, $options);
}
public function init(){
parent::init();
}
/**
* Shortcut for adding an input type text element
* #param string $name name of the item
* #param string $label label of the item
* #param string $id unique HTML id of the item
* #param array $attributes array of attributes to apply to the item
* #param string $labelClass label class(espacially for required item)
*/
public function addHiddenElement($name,$attributes=[]){
$this->add([
'name' => $name,
'type' => Hidden::class,
'attributes' => $attributes,
]);
}
public function addText($name,$label,$id='',$attributes=[],$labelClass=''){
$this->add([
'name' => $name,
'type' => 'text',
'options' => [
'label' => $label,
'id' => $id,
'label_attributes' => [
'class' => $labelClass
],
],
'attributes' => $attributes,
]);
}
/**
* Shortcut for adding an input type text element
* #param string $name name of the item
* #param string $label label of the item
* #param string $id unique HTML id of the item
* #param array $attributes array of attributes to apply to the item
* #param string $labelClass label class(espacially for required item)
*/
public function addFile($name,$label,$id='',$attributes=[],$labelClass=''){
$this->add([
'name' => $name,
'type' => 'file',
'options' => [
'label' => $label,
'id' => $id,
'label_attributes' => [
'class' => $labelClass
],
],
'attributes' => $attributes,
]);
}
public function addTextarea($name,$label,$id='',$attributes=[],$labelClass=''){
$this->add([
'name' => $name,
'type' => 'textarea',
'options' => [
'label' => $label,
'id' => $id,
'label_attributes' => [
'class' => $labelClass
],
],
'attributes' => $attributes,
]);
}
/**
* Shortcut for adding a select list type element
* #param string $name name of the select item
* #param string $label label of the select item
* #param array $valueOptions array values to populate the Select with
* #param array $attributes array of attributes to apply to the Select item
* #param string $labelClass label class(espacially for required item)
*/
public function addSelect($name,$label,$valueOptions=[],$attributes=[],$labelClass=''){
$this->add([
'name' => $name,
'type' => Select::class,
'options' => [
'label' => $label,
'value_options' => $valueOptions,
'label_attributes' => [
'class' => $labelClass
],
],
'attributes' => $attributes,
]);
}
public function addSelectFromTable($name,$label,$type,$attributes=[],$labelClass=''){
$this->add([
'name' => $name,
'type' => get_class($type) ,
'options' => [
'label' => $label,
'label_attributes' => [
'class' => $labelClass
],
],
//'label_attributes' => ['class' => $labelClass],
'attributes' => $attributes,
]);
}
/**
* Shortcut for adding a select list type element
* #param string $name name of the select item
* #param string $label label of the select item
* #param string $id id of the select item
* #param string $checkedValue value of checked item.
* #param string $unCheckedValue value of unchecked item.
* #param array $attributes attribute array.
* #param string $labelClass label class(espacially for required item)
*/
public function addCheckbox($name,$label,$id='',$checkedValue='',$unCheckedValue='',$attributes=[],$labelClass=''){
$this->setLabelAttributes(['class' => $labelClass]);
$this->add([
'name' => $name,
'type' => Checkbox::class,
'options' => [
'label' => $label,
'id' => $id,
'use_hidden_element' => true,
'checked_value' => $checkedValue,
'unchecked_value' => $unCheckedValue,
'label_attributes' => [
'class' => $labelClass
],
],
'attributes' => $attributes,
]);
}
public function addMultiCheckbox($name,$label,$id='',$valueOptions=[],$attributes=[],$labelClass=''){
$this->add([
'name' => $name,
'type' => MultiCheckbox::class,
'options' => [
'label' => $label,
'id' => $id,
'value_options' => $valueOptions,
'label_attributes' => [
'class' => $labelClass
],
],
'attributes' => $attributes,
]);
}
public function addButton($name,$label,$attributes=[]){
$this->add([
'name' => $name,
'type' => Button::class,
'options' => [
'label' => $label,
],
'attributes' => $attributes,
]);
}
/**
* Shortcut for adding a collection list type element
* #param string $name name of the select item
* #param string $label label of the select item
* #param string $targetElement name of the target fieldset
* #param boolean $isObject indicate if the variable is an instance of a class or just a string
* #param int $count number of visible row
* #param boolean $shouldCreateTemplate indicate if the html markup must be created
* #param boolean $allowAdd indicate if new item can to addeds
*/
private function getStringFromElement($element){
if(gettype($element)==='object'){
return get_class($element);
}elseif(gettype($element)==='string'){
return $element;
}else{
throw new \Exception('This type cannot be used with collection element');
}
}
public function addCollection($name,$label, $targetElement,$count=2,$attributes=[],$templatePlaceholder='__index__',$shouldCreateTemplate=true,$allowAdd=true){
$this->add([
'type' => \Laminas\Form\Element\Collection::class,
'name' => $name,
'options' => [
'label' => $label,
'count' => $count,
'should_create_template' => $shouldCreateTemplate,
'template_placeholder' => $templatePlaceholder,
'allow_add' => $allowAdd,
'target_element' => [
'type' => $this->getStringFromElement($targetElement),
],
],
'attributes' => $attributes,
]);
}
}
When I do a var_dump in my init() function in EffetRapportFielset, I get this
And in the same page I get also this :
I need to say that when I do echo on $this->parameters on my RapportEffetForm I get my correct parameter value.
I do not know why for the first time, the value is good, and the (2nd time ??) is null. Do not know also why this value is shown more than once.
Here are all my infos. Hope it helps you to also help me finding a solution.
Best regards !
My intelligent guess is, that the problem is your CommunForm::addFieldsetWithParameters() method. You're loosing the parameters, since you'r creating the fieldset a second time, without the parameters getting passed again.
Just use Laminas\Form\Form::add() to add the fieldset:
$myFieldset = $this->getFormFactory()
->getFormElementManager()
->get(RapportEffetFieldset::class, ['params' => $this->parameters]);
$this->add($myFieldset);
And you do the same thing within the collection. Just pass the object to the collection there as "target_element":
$myFieldset = $this->getFormFactory()
->getFormElementManager()
->get(EffetRapportFieldset::class, ['params' => $this->params]);
$this->add([
'type' => \Laminas\Form\Element\Collection::class,
'name' => 'effets',
'options' => [
'label' => '',
'count' => 1,
'should_create_template' => false,
'template_placeholder' => '__index__',
'allow_add' => false,
'target_element' => $myFieldset,
],
'attributes' => []
]);

many to many save data

I have two entity that have manytomany relation
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Esame
*
* #ORM\Table(name="esame", indexes={#ORM\Index(name="id_tipologia_esame", columns={"id_tipologia_esame"}), #ORM\Index(name="id_analisi", columns={"id_analisi"})})
* #ORM\Entity(repositoryClass="AppBundle\Repository\EsameRepository")
*/
class Esame
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \AppBundle\Entity\Nome_esame
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Nome_esame")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id_tipologia_esame", referencedColumnName="id")
* })
*/
private $idTipologiaEsame;
/**
* #var \AppBundle\Entity\Analisi
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Analisi")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id_analisi", referencedColumnName="id")
* })
*/
private $idAnalisi;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\TipologiaCampione", inversedBy="esami")
*/
private $campioni;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set idAnalisi
*
* #param \AppBundle\Entity\Analisi $idAnalisi
*
* #return Esame
*/
public function setIdAnalisi($idAnalisi)
{
$this->idAnalisi = $idAnalisi;
return $this;
}
/**
* Get idAnalisi
*
* #return int
*/
public function getIdAnalisi()
{
return $this->idAnalisi;
}
/**
* Constructor
*/
public function __construct()
{
$this->campioni = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add campioni
*
* #param \AppBundle\Entity\TipologiaCampione $campioni
*
* #return Esame
*/
public function addCampioni(\AppBundle\Entity\TipologiaCampione $campioni)
{
$this->campioni[] = $campioni;
return $this;
}
/**
* Remove campioni
*
* #param \AppBundle\Entity\TipologiaCampione $campioni
*/
public function removeCampioni(\AppBundle\Entity\TipologiaCampione $campioni)
{
$this->campioni->removeElement($campioni);
}
/**
* Get campioni
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getCampioni()
{
return $this->campioni;
}
/**
* Set idTipologiaEsame
*
* #param \AppBundle\Entity\Nome_esame $idTipologiaEsame
*
* #return Esame
*/
public function setIdTipologiaEsame(\AppBundle\Entity\Nome_esame $idTipologiaEsame = null)
{
$this->idTipologiaEsame = $idTipologiaEsame;
return $this;
}
/**
* Get idTipologiaEsame
*
* #return \AppBundle\Entity\Nome_esame
*/
public function getIdTipologiaEsame()
{
return $this->idTipologiaEsame;
}
}
and Entity 2
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* TipologiaCampione
*
* #ORM\Table(name="tipologia_campione")
* #ORM\Entity(repositoryClass="AppBundle\Repository\TipologiaCampioneRepository")
*/
class TipologiaCampione
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="tipologia", type="string", length=255, nullable=true)
*/
private $tipologia;
/**
* #var string
*
* #ORM\Column(name="matricola", type="string", length=255, nullable=true)
*/
private $matricola;
/**
* #var string
*
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Esame",mappedBy="campioni")
*/
private $esami;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set tipologia
*
* #param string $tipologia
*
* #return TipologiaCampione
*/
public function setTipologia($tipologia)
{
$this->tipologia = $tipologia;
return $this;
}
/**
* Get tipologia
*
* #return string
*/
public function getTipologia()
{
return $this->tipologia;
}
/**
* Set matricola
*
* #param string $matricola
*
* #return TipologiaCampione
*/
public function setMatricola($matricola)
{
$this->matricola = $matricola;
return $this;
}
/**
* Get matricola
*
* #return string
*/
public function getMatricola()
{
return $this->matricola;
}
/**
* Constructor
*/
public function __construct()
{
$this->esami = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add esami
*
* #param \AppBundle\Entity\Esame $esami
*
* #return TipologiaCampione
*/
public function addEsami(\AppBundle\Entity\Esame $esami)
{
$this->esami[] = $esami;
return $this;
}
/**
* Remove esami
*
* #param \AppBundle\Entity\Esame $esami
*/
public function removeEsami(\AppBundle\Entity\Esame $esami)
{
$this->esami->removeElement($esami);
}
/**
* Get esami
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getEsami()
{
return $this->esami;
}
}
now i must save data and in my controller i write this:
for($i=0;$i<$form->get('numero_campioni')->getData();$i++) {
$campione=new TipologiaCampione();
$campione->setMatricola($form['matricola_'.$i]->getData());
$campione->setTipologia($form['tipologia_'.$i]->getData());
foreach($form['esame_'.$i]->getData() as $value){
$tipo_esame = $this->getDoctrine()
->getRepository('AppBundle:nome_esame')
->find($value->getId());
$esame=new Esame();
$esame->setIdAnalisi($analisi);
$esame->setIdTipologiaEsame($tipo_esame);
$em->persist($esame);
$em->flush();
$campione->addEsami($esame); -> this don't work
}
$em->persist($campione);
$em->flush();
}
I expect that $campione->addEsami($esame); creates a new record in my table esame_tipologia_campione for each $campione but it doesn't work ..
My form Type:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Validator\Constraints\DateTime;
use AppBundle\Entity\anagrafica;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use AppBundle\Form\anagraficaType;
use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use AppBundle\Form\EsameType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class AnalisiType extends AbstractType {
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options) {
$province = array(
'AG' => 'Agrigento',
'AL' => 'Alessandria',
'AN' => 'Ancona',
);
$builder->add('ruminanti', ChoiceType::class, array(
'label' => false,
'mapped' => false,
'placeholder' => 'Tipologia di modulo',
'choices' => array('Ruminanti' => 'Ruminanti', 'Suini' => 'Suini'),
'required' => true,
'data' => ($options['data']->getTipoModulo() != NULL ? $options['data']->getTipoModulo() : ''),
'attr' => array(
'placeholder' => 'Provincia',
)))
->add('idLaboratorio', EntityType::class, array(
'label' => false,
'placeholder' => 'Laboratorio a cui inviare i dati',
'class' => 'AppBundle:Laboratorio',
'choice_label' => 'nome',
// 'data'=>5
))
// Dati proprietario
->add('privato', ChoiceType::class, array(
'label' => false,
'choices' => array('Privato' => 'Privato', 'Azienda' => 'Azienda'),
'data' => 'Privato',
'expanded' => true,
'multiple' => false,
'mapped' => false,
))
->add('Nome_proprietario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getNome() : ''),
'attr' => array(
'placeholder' => 'Nome',
'novalidate' => 'novalidate'
)))
->add('Cognome_proprietario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getCognome() : ''),
'attr' => array(
'placeholder' => 'Cognome',
'novalidate' => 'novalidate'
)))
->add('Ragione_sociale_proprietario', TextType::class, array(
'label' => false,
'mapped' => false,
'required' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getRagioneSociale() : ''),
'attr' => array(
'placeholder' => 'Ragione Sociale',
'novalidate' => 'novalidate'
)))
->add('Via_proprietario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getvia() : ''),
'attr' => array(
'placeholder' => 'Via'
)))
->add('Comune_proprietario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getComune() : ''),
'attr' => array(
'placeholder' => 'Comune'
)))
->add('Provincia_proprietario', ChoiceType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getProvincia() : ''),
'choices' => $province,
'placeholder' => 'Provincia'
))
->add('Telefono_proprietario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->gettel() : NULL),
'attr' => array(
'placeholder' => 'Telefono'
)))
->add('email_proprietario', EmailType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getemail() : ''),
'attr' => array(
'placeholder' => 'E-mail'
)
))
->add('Cod_allev_proprietario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getCodiceAllievo() : ''),
'attr' => array(
'placeholder' => 'Codice Allevamento'
)))
// Dati Veterinario
->add('Nome_veterinario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdVeterinario() != NULL ? $options['data']->getIdProprietario()->getNome() : ''),
'attr' => array(
'placeholder' => 'Nome'
)))
->add('Cognome_veterinario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdVeterinario() != NULL ? $options['data']->getIdProprietario()->getCognome() : ''),
'attr' => array(
'placeholder' => 'Cognome'
)))
->add('Via_veterinario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdVeterinario() != NULL ? $options['data']->getIdVeterinario()->getvia() : ''),
'attr' => array(
'placeholder' => 'Via'
)))
->add('Comune_veterinario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdVeterinario() != NULL ? $options['data']->getIdVeterinario()->getComune() : ''),
'attr' => array(
'placeholder' => 'Comune'
)))
->add('Provincia_veterinario', ChoiceType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdVeterinario() != NULL ? $options['data']->getIdVeterinario()->getProvincia() : ''),
'choices' => $province,
'attr' => array(
'placeholder' => 'Provincia'
)))
->add('Telefono_veterinario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdVeterinario() != NULL ? $options['data']->getIdVeterinario()->getTel() : NULL),
'attr' => array(
'placeholder' => 'Telefono'
)))
->add('email_veterinario', EmailType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdVeterinario() != NULL ? $options['data']->getIdVeterinario()->getEmail() : ''),
'attr' => array(
'placeholder' => 'E-mail'
)
))
->add('trattamenti', TextareaType::class, array(
'label' => false,
'attr' => array(
'placeholder' => 'Trattamenti(inserire ANAMNESI; SINTOMATOLOGIA; TRATTAMENTI)'
)
))
->add('vacinazione', TextareaType::class, array(
'label' => false,
'attr' => array(
'placeholder' => 'Vacinazioni(obbligatorio)'
)
))
->add('numero_campioni', NumberType::class, array(
'label' => false,
'attr' => array(
'placeholder' => 'Numero Totale di campioni'
)
));
//->add('save', SubmitType::class, array('label' => 'Create Task'));
$builder->add('idTipologiaEsame', EntityType::class, array(
'label' => false,
'mapped' => false,
'class' => 'AppBundle:Nome_esame',
'choice_label' => 'nome',
'group_by' => 'idCategoriaEsame.tipo',
))
->add('Aggiungi', ButtonType::class, array(
'attr' => array(
'class' => 'btn-primary col-md-2 conferma_esame'),
))
->add('Rimuovi', ButtonType::class, array(
'attr' => array(
'class' => 'btn-primary col-md-2 conferma_esame'),
));
// for($i=0;$i<$options['data']->getNumeroCampioni();$i++){
for ($i = 0; $i < 60; $i++) {
$builder->add('checkbox_' . $i, CheckboxType::class, array(
'label' => false,
'required' => false,
'mapped' => false,
'attr' => array(
'class' => 'check_box_table',
// 'class'=>'col-md-1 col-xs-3 allineare_sinistra',
)
))
->add('matricola_' . $i, TextType::class, array(
'label' => false,
'mapped' => false,
'required' => false,
'attr' => array(
'placeholder' => 'Matricola (FACOLTATIVA)',
// 'class'=>'col-md-2 col-xs-9 allineare_sinistra',
)))
->add('tipologia_' . $i, TextType::class, array(
'label' => false,
'mapped' => false,
'required' => false,
'attr' => array(
'placeholder' => 'Tipologia (FACOLTATIVA)',
// 'class'=>'col-md-2 col-md-offset-0 col-xs-9 col-xs-offset-3 allineare_sinistra',
)))
->add('esame_' . $i, EntityType::class, array(
'label' => false,
'mapped' => false,
'class' => 'AppBundle:Nome_esame',
'required'=>true,
'multiple'=>true,
'choice_label' => 'nome',
// 'disabled' => 'disabled',
'attr' => array(
'placeholder' => 'Esami',
'class' => 'max_width esame_row select_esame',
// 'class'=>'col-md-12 col-md-offset-0 col-xs-9 col-xs-offset-3 ',
)
))
->add('Stampa', ButtonType::class, array(
'disabled' => 'disabled',
'attr' => array(
'class' => 'btn-primary text-center',
)
))
->add('saveAndAdd', SubmitType::class, array('label' => 'Save and Add'))
;
}
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Analisi'
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix() {
return 'appbundle_analisi';
}
}
$esame entity and $campione entity are correctly saved.
Can anybody say to me what I'm doing wrong??
You need to create a Join Table
After that you need to choose which entity is the owner of the association (just after the manytomany chapter in the doc).
For exampre, if you may want to add "campioni" via the "esami" entity you should code a setter like this:
public function addCampioni(\AppBundle\Entity\TipologiaCampione($campioni) {
$campioni->addEsami($this);
$this->campioni[] = $campioni;
return $this;
}
Ciao!

Array to string conversion during POST only

There are questions with the same title but they aren't related to POSTing.
If I submit my form using Symfony I can submit with no problem. Problem is when I submit my form using Angular using via POST method I created. It gives me the exception "Notice: Array to string conversion".
I know it has to do with my ManyToMany Relation (owners). If I don't add any owners it works fine. Problem is when I add owners.
Here is my Stack Trace:
Stack Trace:
1. in vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php at line 106
2. at ErrorHandler ->handleError ('8', 'Array to string conversion', '/Applications/MAMP/htdocs/uploader/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php', '106', array('v' => array('id' => '2', 'firstName' => 'Albert', 'lastName' => 'Jankowski', 'username' => 'ajankowski', 'password' => '$2y$13$7lXTaq3w45j3P0HEln71T.ItLxxf8ZX28UkNFpYFPULyR2a7pLW1C', 'email' => 'ajankowski#myemail.com', 'enabled' => true, 'salt' => null, 'usernameCanonical' => 'ajankowski', 'availableRoles' => array('ROLE_USER', 'ROLE_ADMIN'), 'emailCanonical' => 'ajankowski#myemail.com', 'plainPassword' => null, 'lastLogin' => null, 'confirmationToken' => null, 'roles' => array('ROLE_USER'), 'accountNonExpired' => true, 'accountNonLocked' => true, 'credentialsNonExpired' => true, 'credentialsExpired' => false, 'expired' => false, 'locked' => false, 'superAdmin' => false, 'user' => false, 'passwordRequestedAt' => null, 'groups' => array(), 'groupNames' => array())))
in vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php at line 106
3. at ORMQueryBuilderLoader ->Symfony\Bridge\Doctrine\Form\ChoiceList\{closure} (array('id' => '2', 'firstName' => 'Albert', 'lastName' => 'Jankowski', 'username' => 'ajankowski', 'password' => '$2y$13$7lXTaq3w45j3P0HEln71T.ItLxxf8ZX28UkNFpYFPULyR2a7pLW1C', 'email' => 'ajankowski#myemail.com', 'enabled' => true, 'salt' => null, 'usernameCanonical' => 'ajankowski', 'availableRoles' => array('ROLE_USER', 'ROLE_ADMIN'), 'emailCanonical' => 'ajankowski#myemail.com', 'plainPassword' => null, 'lastLogin' => null, 'confirmationToken' => null, 'roles' => array('ROLE_USER'), 'accountNonExpired' => true, 'accountNonLocked' => true, 'credentialsNonExpired' => true, 'credentialsExpired' => false, 'expired' => false, 'locked' => false, 'superAdmin' => false, 'user' => false, 'passwordRequestedAt' => null, 'groups' => array(), 'groupNames' => array()))
4. at array_filter (array(array('id' => '2', 'firstName' => 'Albert', 'lastName' => 'Jankowski', 'username' => 'ajankowski', 'password' => '$2y$13$7lXTaq3w45j3P0HEln71T.ItLxxf8ZX28UkNFpYFPULyR2a7pLW1C', 'email' => 'ajankowski#myemail.com', 'enabled' => true, 'salt' => null, 'usernameCanonical' => 'ajankowski', 'availableRoles' => array('ROLE_USER', 'ROLE_ADMIN'), 'emailCanonical' => 'ajankowski#myemail.com', 'plainPassword' => null, 'lastLogin' => null, 'confirmationToken' => null, 'roles' => array('ROLE_USER'), 'accountNonExpired' => true, 'accountNonLocked' => true, 'credentialsNonExpired' => true, 'credentialsExpired' => false, 'expired' => false, 'locked' => false, 'superAdmin' => false, 'user' => false, 'passwordRequestedAt' => null, 'groups' => array(), 'groupNames' => array())), object(Closure))
in vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php at line 107
My Entity:
/**
* Company
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="AppBundle\Repository\CompanyRepository")
*/
class Company
{
......
......
/**
* #var User
*
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\User")
*/
private $owners;
......
......
}
My Controller:
/**
* #Route("", name="api_company_create")
* #Method("POST")
*
* #param \Symfony\Component\HttpFoundation\Request $request
*
* #return Response $response
*/
public function createAction(Request $request)
{
// Process the form.
$company = new Company();
$form = $this->createForm(new CompanyType(), $company);
$this->processForm($request, $form, TRUE);
if (!$form->isValid()) {
$this->throwApiProblemValidationException($form);
}
$em = $this->getDoctrine()->getManager();
$em->persist($company);
$em->flush();
$response = $this->createApiResponse($company, 201);
$companyUrl = $this->generateUrl(
'api_company_show',
['id' => $company->getId()] );
$response->headers->set('Location', $companyUrl);
return $response;
}
/**
* Process the form.
*
* #param \Symfony\Component\HttpFoundation\Request $request
* #param \Symfony\Component\Form\FormInterface $form
* #param boolean $removeExtraFields
* #param Company $currentCompany
*/
private function processForm(Request $request, FormInterface $form, $removeExtraFields = FALSE, $currentCompany = NULL)
{
$data = json_decode($request->getContent(), true);
$clearMissing = $request->getMethod() != 'PATCH';
$form->submit($data, $clearMissing);
}
/**
* Company
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="AppBundle\Repository\CompanyRepository")
*/
class Company
{
......
......
/**
* #var User
*
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\User")
*/
private $owners;
......
......
}
I tried adding __String() to my Company Entity but that didn't help.
/**
* Transform to string
*
* #return string
*/
public function __toString()
{
return (string) $this->getOwners();
}
I was able to figure this out. It was because Symfony(Doctrine) does not want an entire object back. I created a function in my controller to fix this.
/**
* You may receive an entire object for a relation from your api but when
* saving Doctrine only wants the ids.
*
* For Example your API returns:
* $data['owners'][0] = array('id' => 1, 'name' => 'Admin');
* $data['owners'][1] = array('id' => 2, 'name' => 'User');
*
* But it expects:
*
* $data['owners'][0] = 1;
* $data['owners'][1] = 2;
*
*
* #param array $data
* #param string $name
*/
private function convertRelationToDoctrineSafeArray(&$data, $name)
{
if (isset($data[$name]) && $data[$name]) {
foreach ($data[$name] as $key => $field) {
$fields[$key] = $field['id'];
}
unset($data[$name]);
$data[$name] = $fields;
}
}

Load a page with drupal ajax from javascript

I am working on a Drupal module that provides a jvectormap node type.
Everything works fine except the drupal .load(). I use
jQuery("#content").load(Drupal.settings.jvectormapnode.url+'/'+ code +'?ajax=1');
The following happens i click a country on the map and this calls /content/institutes/BE
/content/institutes is an views page with a contextual filter witch grabs the last part of the url and displays some data.
The jvectormap node is included on this same page trough a mini-panel and blocks (the view resides in div #content and the jvectormap in a mini-panel block)
Up to this point everything is ok. Now when i click a second region the URL suddenly switches to /content/undefined.
Let me clarify with an example: I click on Belgium the URL changes to /content/institutes/BE and the view picks this up, then I click France and the URL changes to /content/undefined but the view still reacts correctly and shows the France info. Now I hit F5 to refresh the browser and drupal says that /content/undefined does not exist. If I hit F5 after the first click (Belgium) it reloads the page correctly. The problem seems to happen with consecutive ajax requests. I coud fix this with an url alias so this would handle the F5 refresh edge case seeing everything else works correctly, but if some one else needs more than one node they have a (small) problem.
I suspect the .load is the reason why this is happening.
Any help is welcome thanks.
jvectormapnode.js
(function ($)
{
Drupal.behaviors.jvectormapnode =
{
attach: function (context, settings)
{
$('#jvectormapnode').once('jvectormapnode', function() { //fix duplicating behavior when using ajax
highlighted=JSON.parse(Drupal.settings.jvectormapnode.coloredregions);
//console.log(Drupal.settings.jvectormapnode.coloredregions);
//console.log(highlighted);
//change color of clicked region ==> todo
/*
currentSelected = '';
defaultColor = '#00FF00';
selectedColor = '#FF00FF';
maphandle = $('#map-teste');
maphandle.vectorMap({
map: 'br_en',
onRegionClick: function(event, code){
if(currentSelected !== code) {
if(currentSelected !== ''){
// Deselect, then select new choice
maphandle.vectorMap('set', 'colors', currentSelected, defaultColor);
maphandle.vectorMap('set', 'colors', code, selectedColor);
currentSelected = code;
} else {
// Nothing currently selected, go ahead and select
maphandle.vectorMap('set', 'colors', code, selectedColor);
currentSelected = code;
}
} else {
// Deselect
maphandle.vectorMap('set', 'colors', code, defaultColor);
currentSelected = '';
}
alert(code); // return the state
}
});*/
$('#jvectormapnode').vectorMap({
map: 'world_mill_en',
focusOn: {
x: Drupal.settings.jvectormapnode.x,
y: Drupal.settings.jvectormapnode.y,
scale: Drupal.settings.jvectormapnode.scale
},
color: '#aaaaaa',
hoverColor: false,
hoverOpacity: 0.5,
backgroundColor: 'false',
onRegionClick: function (event, code) {
//if(typeof(afunctiontodo!='undefined') afunctiontodo();
//else
//{
//window.location = Drupal.settings.jvectormapnode.url+'/'+ code;
jQuery("#content").load(Drupal.settings.jvectormapnode.url+'/'+ code +'?ajax=1');
//$('#jvectormapnode').vectorMap('set', 'focus', code);
//showSelectedCountry;
//}
},
series: {
regions: [{
values: highlighted ,
attribute: 'fill'
}]
}
});
});
}
};
}(jQuery));
jvectormapnode.module
<?php
/**
* #file
*/
/**
* #defgroup jvectormapnode : Node
* #ingroup jvectormapnode
* #{
* 20130812 pieterm
* Integrates jvectormapnode into Drupal through the node type system
*/
/**
* Implements hook_libraries_info().
*/
function jvectormapnode_libraries_info() {
$libraries['jvectormap'] = array(
'name' => 'jVectorMap',
'vendor url' => 'http://jvectormap.com/',
'download url' => 'http://jvectormap.com/download/',
'version arguments' => array(
'file' => 'jquery.jvectormap.min.js',
'pattern' => '#jVectorMap version ([0-9\.]+)#',
'lines' => 2,
'cols' => 30,
),
'versions' => array(
'1.2.2' => array(
'files' => array(
'js' => array('jquery.jvectormap.min.js'),
'css' => array('jquery.jvectormap.css'),
),
),
),
);
return $libraries;
}
/**
* Implements hook_view().
*/
function jvectormapnode_view($node, $view_mode) {
$node->content['jvectormapnodebody'] = array(
'#markup' => _jvectormapnode_page($node),
'#weight' => 1,
);
return $node;
}
/**
* Implements hook_theme().
* Overriding the default node template for jvectormapnode pages
*/
function jvectormapnode_theme($existing, $type, $theme, $path) {
$items = array(
'node__jvectormapnode' => array(
// Don't specify the path in the template name.
// Unless you have your template inside a directory within this module.
'template' => 'templates/node--jvectormapnode',
'variables' => array('node' => (object)array()),
// If you want to put the tpl in another location, you can use this key.
//'theme path' => drupal_get_path('module', 'another_module'),
),
);
return $items;
}
/**
* Implements hook_node_info().
*
* We use hook_node_info() to define our node content type.
*/
function jvectormapnode_node_info() {
// We define the node type as an associative array.
return array(
'jvectormapnode' => array(
'name' => t('jvectormapnode'),
'base' => 'jvectormapnode', //function prefix hooks
'description' => t('This is the jvectormapnode node type. It can display interactive maps.'),
'title_label' => t('jvectormapnode page title'),
'locked' => FALSE, //TODO SET TRUE
),
);
}
/**
* Implements hook_node_type_insert().
* lets us know that a new content type has been inserted.
* this gives us a chance to add the fields we want. (called for all node isnert!==>check type)
*/
function jvectormapnode_node_type_insert($content_type) {
if ($content_type->type == 'jvectormapnode') {
// Add default body field
$body_instance = node_add_body_field($content_type, t('Information you want to show on each page before the content of the jvectormapnode module'));
$body_instance['display']['example_node_list'] = array(
'label' => 'hidden',
'type' => 'text_summary_or_trimmed',
);
// Save our changes to the body field instance.
field_update_instance($body_instance);
// Create all the fields we are adding to our content type.
foreach (_jvectormapnode_installed_fields() as $field) {
field_create_field($field);
}
// Create all the instances for our fields.
foreach (_jvectormapnode_installed_instances() as $instance) {
$instance['entity_type'] = 'node';
$instance['bundle'] = 'jvectormapnode';
field_create_instance($instance);
}
}
}
/**
* Define the fields for our content type.
*
* This big array is factored into this function for readability.
*
* #return
* An associative array specifying the fields we wish to add to our
* new node type.
*/
function _jvectormapnode_installed_fields() {
return array(
'jvectormapnode_field_color' => array(
'field_name' => 'jvectormapnode_field_color',
'cardinality' => 1,
'type' => 'text',
),
'jvectormapnode_field_url' => array(
'field_name' => 'jvectormapnode_field_url',
'cardinality' => 1,
'type' => 'text',
),
'jvectormapnode_field_width' => array(
'field_name' => 'jvectormapnode_field_width',
'cardinality' => 1,
'type' => 'text',
),
'jvectormapnode_field_height' => array(
'field_name' => 'jvectormapnode_field_height',
'cardinality' => 1,
'type' => 'text',
),
'jvectormapnode_field_regions' => array(
'field_name' => 'jvectormapnode_field_regions',
'cardinality' => 1,
'type' => 'text',
),
'jvectormapnode_field_scale' => array(
'field_name' => 'jvectormapnode_field_scale',
'cardinality' => 1,
'type' => 'text',
),
'jvectormapnode_field_x' => array(
'field_name' => 'jvectormapnode_field_x',
'cardinality' => 1,
'type' => 'text',
),
'jvectormapnode_field_y' => array(
'field_name' => 'jvectormapnode_field_y',
'cardinality' => 1,
'type' => 'text',
),
);
}
/**
* Define the field instances for our content type.
*
* The instance lets Drupal know which widget to use to allow the user to enter
* data and how to react in different view modes.
*
* This big array is factored into this function for readability.
*
* #return
* An associative array specifying the instances we wish to add to our new
* node type.
*/
function _jvectormapnode_installed_instances() {
return array(
'jvectormapnode_field_url' => array(
'field_name' => 'jvectormapnode_field_url',
'label' => t('URL, format http://www.vliz.be/en/...'),
'widget' => array(
'type' => 'text_textfield',
),
),
'jvectormapnode_field_width' => array(
'field_name' => 'jvectormapnode_field_width',
'label' => t('Map width, format px or %'),
'widget' => array(
'type' => 'text_textfield',
),
),
'jvectormapnode_field_height' => array(
'field_name' => 'jvectormapnode_field_height',
'label' => t('Map height, format px or %'),
'widget' => array(
'type' => 'text_textfield',
),
),
'jvectormapnode_field_regions' => array(
'field_name' => 'jvectormapnode_field_regions',
'label' => t('Regions to be highlighted'),
'widget' => array(
'type' => 'text_textfield',
),
),
'jvectormapnode_field_color' => array(
'field_name' => 'jvectormapnode_field_color',
'label' => t('Highlight color, HEX format #ffffff.'),
'widget' => array(
'type' => 'text_textfield',
),
),
'jvectormapnode_field_scale' => array(
'field_name' => 'jvectormapnode_field_scale',
'label' => t('Initial zoom, nummeric format.'),
'widget' => array(
'type' => 'text_textfield',
),
),
'jvectormapnode_field_x' => array(
'field_name' => 'jvectormapnode_field_x',
'label' => t('Initial x-axis focus, nummeric format.'),
'widget' => array(
'type' => 'text_textfield',
),
),
'jvectormapnode_field_y' => array(
'field_name' => 'jvectormapnode_field_y',
'label' => t('Initial y-axis focus, nummeric format.'),
'widget' => array(
'type' => 'text_textfield',
),
),
);
}
/**
* Implements hook_entity_info_alter().
*
* We need to modify the default node entity info by adding a new view mode to
* be used in functions like node_view() or node_build_content().
*/
function jvectormapnode_entity_info_alter(&$entity_info) {
// Add our new view mode to the list of view modes...
$entity_info['node']['view modes']['example_node_list'] = array(
'label' => t('Example Node List'),
'custom settings' => TRUE,
);
}
/**
* Implement hook_form().
*
* Drupal needs for us to provide a form that lets the user
* add content. This is the form that the user will see if
* they go to node/add/node-example.
*/
function jvectormapnode_form($node, $form_state) {
return node_content_form($node, $form_state);
}
/**
* Implements hook_field_formatter_info().
*/
function jvectormapnode_field_formatter_info() {
return array(
'jvectormapnode_field_color' => array(
'label' => t('jvectormapnode color Handle'),
'field types' => array('text'),
),
'jvectormapnode_field_url' => array(
'label' => t('jvectormapnode url Handle'),
'field types' => array('text'),
),
'jvectormapnode_field_width' => array(
'label' => t('jvectormapnode width Handle'),
'field types' => array('text'),
),
'jvectormapnode_field_height' => array(
'label' => t('jvectormapnode height Handle'),
'field types' => array('text'),
),
'jvectormapnode_field_regions' => array(
'label' => t('jvectormapnode regions Handle'),
'field types' => array('text'),
),
'jvectormapnode_field_scale' => array(
'label' => t('jvectormapnode scale Handle'),
'field types' => array('text'),
),
'jvectormapnode_field_x' => array(
'label' => t('jvectormapnode x Handle'),
'field types' => array('text'),
),
'jvectormapnode_field_y' => array(
'label' => t('jvectormapnode y Handle'),
'field types' => array('text'),
),
);
}
/**
* Implements hook_help().
*/
function jvectormapnode_help($path, $arg) {
switch ($path) {
case 'examples/jvectormapnode':
return "<p>" . t("The Node Example module provides a custom node type.
You can create new Example Node nodes using the <a href='!nodeadd'>node add form</a>.",
array('!nodeadd' => url('node/add/node-example'))) . "</p>";
}
}
/**
* Page callback to show jvectormapnode
*/
function _jvectormapnode_page($n) {
//get params from drupal entity created by user in add content
$dcolor= field_get_items('node', $n, 'jvectormapnode_field_color');
$dcolor=render(field_view_value('node', $n, 'jvectormapnode_field_color',$dcolor[0]));
$durl= field_get_items('node', $n, 'jvectormapnode_field_url');
$durl=render(field_view_value('node', $n, 'jvectormapnode_field_url',$durl[0]));
$dwidth= field_get_items('node', $n, 'jvectormapnode_field_width');
$dwidth=render(field_view_value('node', $n, 'jvectormapnode_field_width',$dwidth[0]));
$dheight= field_get_items('node', $n, 'jvectormapnode_field_height');
$dheight=render(field_view_value('node', $n, 'jvectormapnode_field_height',$dheight[0]));
$dregions= field_get_items('node', $n, 'jvectormapnode_field_regions');
$dregions=render(field_view_value('node', $n, 'jvectormapnode_field_regions',$dregions[0]));
$dscale= field_get_items('node', $n, 'jvectormapnode_field_scale');
$dscale=render(field_view_value('node', $n, 'jvectormapnode_field_scale',$dscale[0]));
$dx= field_get_items('node', $n, 'jvectormapnode_field_x');
$dx=render(field_view_value('node', $n, 'jvectormapnode_field_x',$dx[0]));
$dy= field_get_items('node', $n, 'jvectormapnode_field_y');
$dy=render(field_view_value('node', $n, 'jvectormapnode_field_y',$dy[0]));
//$coloredregions=array();
$exploderegions = explode(",", $dregions);
$coloredregions=array();
foreach ($exploderegions as $region)
{
$coloredregions[$region] = $dcolor ;
}
$coloredregions_object = json_encode($coloredregions);
$jvectormapnodebody.= '<div style="width: '.$dwidth.'; height: '.$dheight.'" id="jvectormapnode"></div>';
libraries_load('jvectormap');
drupal_add_js('/sites/all/modules/vliz/jvectormapnode/js/maps/jquery-jvectormap-world-mill-en.js');
drupal_add_js(array('jvectormapnode' => array('url' => $durl,'coloredregions'=> $coloredregions_object,'scale' => $dscale,'x' => $dx,'y' => $dy)), 'setting');
drupal_add_js('/sites/all/modules/vliz/jvectormapnode/js/jvectormapnode.js');
return $jvectormapnodebody;
}
/**
* #} End of "defgroup jvectormapnode".
*/
It seems that the code argument passed within the onRegionClick callback is undefined.
Can you do a console.log() of that argument to know the exact value? Normally this should be the region code as a string. (i.e.: 'BE', 'NL', ...)
onRegionClick: function (event, code) {
console.log(code);
}
I found out what was causing the undefined, here's the code that works
jQuery("#content").load(Drupal.settings.jvectormapnode.url+'/'+ code ,'ajax=1' ,
function() {Drupal.attachBehaviors('#content');});
hope this helps someone else

How To Create New Content Type Programmatically in Drupal 7?

I'm building a module (my_module) in Drupal 7.
It has some functionality and also will create new content type.
In my_module.install I implemented the hook_install (my_module_install).
Can I use more one implementation of hook_install to create new content type (my_cck_install) in this module?
If (yes), how should I do this?
Else: have I do this in another module? :-)
You can't use more than one implementation of hook_install in the same module; in PHP you can't have 2 function with the same name which rules this out.
You would just need to add your new content type in the same hook_install anyway (have a look at how the standard installation profile does it at /profiles/standard/standard.install). This is how I always add new content types from the install file (using the example of a testimonials module):
function testimonial_install() {
// Make sure a testimonial content type doesn't already exist
if (!in_array('testimonial', node_type_get_names())) {
$type = array(
'type' => 'testimonial',
'name' => st('Testimonial'),
'base' => 'node_content',
'custom' => 1,
'modified' => 1,
'locked' => 0,
'title_label' => 'Customer / Client Name'
);
$type = node_type_set_defaults($type);
node_type_save($type);
node_add_body_field($type);
}
}
The following code will create a content type called "Event" with a machine name of 'event' and a title field -
//CREATE NEW CONTENT TYPE
function orderform_node_info() {
return array(
'event' => array(
'name' => t('Event'),
'base' => 'event',
'description' => t('A event content type'),
'has_title' => TRUE
),
);
}
function event_form($node,$form_state) {
$form['title'] = array(
'#type' => 'textfield',
'#title' => t('event Title'),
'#default_value' => !empty($node->title) ? $node->title : '',
'#required' => TRUE,
'#weight' => -5
);
return $form;
}
//END CONTENT TYPE
you should place it in your .module file... if you want do add additional fields to it, let me know and I'll patch you up with the code... good luck!
/**
* Implements hook_node_info()
*/
function mymodule_node_info() {
return array(
'news' => array(
'name' => t('News'),
'base' => 'news',
'description' => t('You can add News here'),
'has_title' => TRUE,
'title_label' => t('News title')
)
);
}
/**
* Implement hook_form()
*/
function mymodule_form($node, $form_state) {
return node_content_form($node, $form_state);
}
Add the implementation to mymodule.install is as follows:
/**
* Implements hook_install().
*/
function mymodule_install() {
node_types_rebuild();
$types = node_type_get_types();|
node_add_body_field($types['news']);
}
You can get a detailed description with code from here
/*
* Implementation in hook node info in .Module file
*/
function test_node_info() {
return array(
'product' => array(
'name' => t('Product'),
'base' => 'product',
'description' => t('Product Title'),
)
);
}
/**
* Implement hook_form()
*/
function product_form($node, $form_state) {
return node_content_form($node, $form_state);
}
/**
* Implements hook_install() in .install file.
*/
function test_install() {
node_types_rebuild();
$types = node_type_get_types();
node_add_body_field($types['product']);
//New way to implement to add fields in your content type
foreach (_test_installed_fields() as $field) {
field_create_field($field);
}
foreach (_test_installed_instances() as $fieldinstance) {
$fieldinstance['entity_type'] = 'node';
$fieldinstance['bundle'] = 'product';
field_create_instance($fieldinstance);
}
}
/*
* Define your fields
*/
function _test_installed_fields() {
$t = get_t();
return array(
'product_title123' => array(
'field_name' => 'product_title123',
'label' => $t('Product Title'),
'type' => 'text'
),
'description123' => array(
'field_name' => 'description123',
'label' => $t('Description'),
'type' => 'text'
),
);
}
/*
* Define your instance of fields
*/
function _test_installed_instances() {
$t = get_t();
return array(
'product_title123' => array(
'field_name' => 'product_title123',
'type' => 'text',
'label' => $t('Product Title'),
'widget' => array(
'type' => 'text_textfield'
),
'display' => array(
'example_node_list' => array(
'label' => $t('Product Title'),
'type' => 'text'
)
)
),
'description123' => array(
'field_name' => 'description123',
'type' => 'text',
'label' => $t('Description'),
'widget' => array(
'type' => 'text_textarea_with_summary'
),
'display' => array(
'example_node_list' => array(
'label' => $t('Description'),
'type' => 'text'
)
)
),
);
}
/**
* Implements hook_uninstall().
*/
function test_uninstall() {
$ournewtype = 'product';
$sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
$result = db_query($sql, array(':type' => $ournewtype));
$nodeids = array();
foreach ($result as $row) {
$nodeids[] = $row->nid;
}
node_delete_multiple($nodeids);
node_type_delete($ournewtype);
}
That's it.

Resources