I have a table CustBillingEmployee described in the scheme below
CustBillingEmployee:
connection: doctrine
tableName: cust_billing_employee
columns:
employee_num:
type: integer(4)
fixed: false
unsigned: false
primary: true
autoincrement: false
job_title_code:
type: integer(4)
fixed: false
unsigned: false
primary: false
notnull: true
autoincrement: false
cost:
type: 'decimal(5, 2)'
fixed: false
unsigned: false
primary: false
default: '0.00'
notnull: true
autoincrement: false
relations:
HsHrEmployee:
local: employee_num
foreign: emp_number
type: one
and the class below
class cust_billing_employee extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('employee_num', 'integer',4,array(
'type' => 'integer',
'length' => 4,
'fixed' => false,
'unsigned' => false,
'primary' => true,
'autoincrement' => false,
));
$this->hasColumn('job_title_code', 'integer',4,array(
'type' => 'integer',
'length' => 4,
'fixed' => false,
'unsigned' => false,
'primary' => false,
'notnull' => true,
'autoincrement' => false,
));
$this->hasColumn('cost', 'decimal',5,array(
'fixed' => false,
'unsigned' => false,
'primary' => false,
'default' => '0.00',
'notnull' => true,
'autoincrement' => false,
));
}
public function setUp()
{
$this->hasOne('User', array(
'local' => 'employee_num',
'foreign' => 'emp_number'
));
}
public function __toString() {
return "HI";
}
}
When I try to extract a particular object like so:
echo Doctrine::getTable('CustBillingEmployee')->find(1);
I get an error
No description for object of class "CustBillingEmployee"
I was hoping that the function __toString() gets overridden from the parent class but that is not the case. How shall I add a description to the object then?
When displaying each record I want to be able to display employee name instead of just employee_num key and job title instead of job_title_cost
Can you post whole call stack, what code throws that error?
What is suspicious to me is the name of the class cust_billing_employee not being CustBillingEmployee and not extending BaseCustBillingEmployee which would be default behaviour of Symfony 1.4. Did you wrote this code 'by hand' ?
Since your schema is defined in schema.yml you should be using ./symfony doctrine:build-model task.
This should generate correct classes: CustBillingEmployee extending BaseCustBillingEmployee which extends sfDoctrineRecord and then Doctrine_Core::getTable('CustBillingEmployee')->find(1) should work perfectly.
Also note, that you should not touch BaseCustBillingEmployee as this is meant to be autogenerated code, all modifications (like __toString) should be done in CustBillingEmployee class.
Related
Imaging having the following input for a form request validation.
[
'relations' =>
[
[
'primary' => true,
],
[
'primary' => false,
],
],
],
Is there any validation that makes it possible to secure that at least one of the relations models have primary set to true? More perfect if it could secure only one element is true. This problem seems like it could have existed before.
So if we only see the input for relations, this should pass.
[
'primary' => true,
],
[
'primary' => false,
],
This should fail in validation.
[
'primary' => false,
],
[
'primary' => false,
],
Try an inline custom rule:
public function rules()
{
return [
'relations' => function ($attribute, $relations, $fail) {
$hasPrimary = collect($relations)
->filter(function ($el) {
return $el['primary'];
})
->isNotEmpty();
if ( ! $hasPrimary)
{
$fail($attribute . ' need to have at least one element set as primary.');
}
},
// the rest of your validation rules..
];
}
Of course, you could extract this to a dedicated Rule object, but you get the idea.
I have a form for Namespace\Entity\MainEntity which include a subform like this:
->add('property1', TextType::class, array(
'required' => false,
'label' => 'This is the form label',
'data_class' => 'Namespace\Entity\SubFormEntity',
'attr' => array(
'class' => 'form-control'
)
))
->add('property2', SubFormType::class)
The SubFormType itself has a text field as shown below:
->add('subproperty1', TextType::class, array(
'label' => false,
'attr' => array(
'class' => 'form-control'
)
))
If I submit the form, property1 gets validated correctly but validation for property2 is not triggered and the form gets submitted even though the value for subform_field is incorrect.
I have tried ...
Namespace\Entity\SubFormEntity:
properties:
property2:
- Type:
type: numeric
... and ...
Namespace\Entity\MainEntity:
properties:
property2.subproperty1:
- Type:
type: numeric
How can I enable validation for the subproperty1 field?
Enable error_bubbling (documentation) to have your sub-form's errors show up in the parent form.
Use the following validation mapping for SubFormEntity:
Namespace\Entity\SubFormEntity:
properties:
subproperty1:
- Type:
type: numeric
Add the Valid constraint to your MainEntity's validation mapping:
Namespace\Entity\MainEntity:
properties:
property2:
- Valid
Add the error_bubbling option to your SubFormType:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
// ...
'error_bubbling' => true
));
}
... or add the option dynamically when including your SubFormType in your ParentFormType like this:
->add('property2', SubFormType::class, array(
'error_bubbling' => true
))
I have a form search and i'd like to select data by boolean field. The problem is that if the select choice has false value (0) the query returns all data but if selected choice has true value (1) the query is correct.
In the formTye:
->add('publier', ChoiceType::class, array(
'required' => false,
'label' => 'Publier',
'choices' => array('oui' => '1', 'non' => '0'),
'multiple' => false,
'expanded' => false,
'attr' => array('class'=> 'form-control')
));
and in the query_builder
if (!empty($publier)) {
$qb->andWhere('a.publier = :publier')
->setParameter('publier', $publier );
}
if I remove this test : if (!empty($publier)) { and I select a false choice the returned data is correct but I can't remove this test.
I have changed
if (!empty($publier))
by
if (null !== $publier )
and it works fine now
I'm not sure I understand your question clearly, but if it's a boolean you want, you should try this:
->add('publier', ChoiceType::class, array(
'required' => false,
'label' => 'Publier',
'choices' => array(
'oui' => true,
'non' => false
),
'multiple' => false,
'expanded' => false,
'attr' => array('class'=> 'form-control')
));
Not sure if it will work. The way you have it with '1' and '0', those are strings (not integers).
I've done a bit of searching online but I have not found any answers to this question yet. I have a situation where I need a product attribute that is a decimal value and it must support negative numbers as well as positive and must also be sortable. For some reason, Magento does not have a "decimal" attribute type. The only type that uses decimal values is Price, but that doesn't support negative numbers. If I use "text" as the type, it supports whatever I want, but it doesn't sort properly because it sees the values as strings rather than floating point numbers. I have been able to work around this issue, as others have in posts I've found, by manually editing the eav_attribute table and changing 'frontend_input' from 'price' to 'text', but leaving the 'backend_type' as 'decimal'. This works great...until someone edits the attribute in the admin panel. Once you save the attribute, Magento notices that the frontend_input is 'text' and changes the 'backend_type' to 'varchar'. The only way around this that I can think of is by creating a custom attribute type, but I'm not sure where to start and I can't find any details online for this.
Has anyone else experienced this problem? If so, what have you done to correct it? If I need to create a custom attribute type, do you have any tips or can you point me at any tutorials out there for doing this?
Thanks!
What you want to do is create a custom attribute type.
This can be done by first creating a installer script (this updates the database).
startSetup();
$installer->addAttribute('catalog_product', 'product_type', array(
'group' => 'Product Options',
'label' => 'Product Type',
'note' => '',
'type' => 'dec', //backend_type
'input' => 'select', //frontend_input
'frontend_class' => '',
'source' => 'sourcetype/attribute_source_type',
'backend' => '',
'frontend' => '',
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_WEBSITE,
'required' => true,
'visible_on_front' => false,
'apply_to' => 'simple',
'is_configurable' => false,
'used_in_product_listing' => false,
'sort_order' => 5,
));
$installer->endSetup();
After that you need to create a custom php class named:
Whatever_Sourcetype_Model_Attribute_Source_Type
And in there paste this in:
class Whatever_Sourcetype_Model_Attribute_Source_Type extends Mage_Eav_Model_Entity_Attribute_Source_Abstract
{
const MAIN = 1;
const OTHER = 2;
public function getAllOptions()
{
if (is_null($this->_options)) {
$this->_options = array(
array(
'label' => Mage::helper('sourcetype')->__('Main Product'),
'value' => self::MAIN
),
array(
'label' => Mage::helper('sourcetype')->__('Other Product'),
'value' => self::OTHER
),
);
}
return $this->_options;
}
public function toOptionArray()
{
return $this->getAllOptions();
}
public function addValueSortToCollection($collection, $dir = 'asc')
{
$adminStore = Mage_Core_Model_App::ADMIN_STORE_ID;
$valueTable1 = $this->getAttribute()->getAttributeCode() . '_t1';
$valueTable2 = $this->getAttribute()->getAttributeCode() . '_t2';
$collection->getSelect()->joinLeft(
array($valueTable1 => $this->getAttribute()->getBackend()->getTable()),
"`e`.`entity_id`=`{$valueTable1}`.`entity_id`"
. " AND `{$valueTable1}`.`attribute_id`='{$this->getAttribute()->getId()}'"
. " AND `{$valueTable1}`.`store_id`='{$adminStore}'",
array()
);
if ($collection->getStoreId() != $adminStore) {
$collection->getSelect()->joinLeft(
array($valueTable2 => $this->getAttribute()->getBackend()->getTable()),
"`e`.`entity_id`=`{$valueTable2}`.`entity_id`"
. " AND `{$valueTable2}`.`attribute_id`='{$this->getAttribute()->getId()}'"
. " AND `{$valueTable2}`.`store_id`='{$collection->getStoreId()}'",
array()
);
$valueExpr = new Zend_Db_Expr("IF(`{$valueTable2}`.`value_id`>0, `{$valueTable2}`.`value`, `{$valueTable1}`.`value`)");
} else {
$valueExpr = new Zend_Db_Expr("`{$valueTable1}`.`value`");
}
$collection->getSelect()
->order($valueExpr, $dir);
return $this;
}
public function getFlatColums()
{
$columns = array(
$this->getAttribute()->getAttributeCode() => array(
'type' => 'int',
'unsigned' => false,
'is_null' => true,
'default' => null,
'extra' => null
)
);
return $columns;
}
public function getFlatUpdateSelect($store)
{
return Mage::getResourceModel('eav/entity_attribute')
->getFlatUpdateSelect($this->getAttribute(), $store);
}
}
Hope this helps.
For further info see here.
I can not really find a satisfying answer to the following question:
What would be the best practice for a module to add a new product attribute to all attribute_sets (and possibly at a certain location).
All approaches I can find seem to refer to adding a new attribute to just one attribute set.
There is a magento way for it
Example:
$installer->addAttribute('catalog_product', 'test_me', array(
'label' => 'test Me',
'input' => 'textarea',
'type' => 'text',
'class' => '',
'global' => true,
'visible' => true,
'required' => false,
'user_defined' => true,
'default' => '',
'apply_to' => 'simple,configurable',
'visible_on_front' => true,
'is_configurable' => false,
'wysiwyg_enabled' => true,
'used_in_product_listing' => true,
'is_html_allowed_on_front' => true,
'group' => 'Config',
'sort_order' => 25
));
To add attribute to every attribute_set you need to set 'user_defined' = true and set 'group' = 'your_group_name'. If needed magento will add your group to every attribute set, and attach attribute to it.
Once you add an attribute you may assign it to one or all attribute sets, it isn't unique to the first set you assign it to. Does this answer your question?