I need some validations done, for example, in a date field. I've configured config.sml and config_dev.xml to enable annotations as told in docs. Here is my code:
Entity:
/** *************************************************
* #var date
*
* #Assert\Date(message="Fecha de Nacimiento incorrecta")
* #ORM\Column(name="dfec_nacimiento", type="date", nullable=true)
*/
private $fecNacimiento;
/**
* #param date $fecNacimiento
*/
public function setFecNacimiento($fecNacimiento)
{
$this->fecNacimiento = $fecNacimiento;
}
/**
* #return date
* #Assert\Date()
*/
public function getFecNacimiento()
{
return $this->fecNacimiento;
}
Controller:
[..]
$form = $this->createForm(new IncidenciaType($numSocio,
null,
$listadoTiposIncidencia,
$listadoCentros,
$listadoTiposDoc,
$listadoTiposVia),
$incidencia);
$form->handleRequest($request);//bind del formulario con el request
if ($form->isValid()) {
//Some code
} else {
} else {
$errors = array();
if ($form->count() > 0) {
foreach ($form->all() as $child) {
/**
* #var \Symfony\Component\Form\Form $child
*/
if (!$child->isValid()) {
$errors[$child->getName()] = $this->getErrorMessages($child);
}
}
} else {
/**
* #var \Symfony\Component\Form\FormError $error
*/
foreach ($form->getErrors() as $key => $error) {
$errors[] = $error->getMessage();
}
}
//$errores = array('1' => 'Existen errores en los datos');
return $this->render('Bundle:Environment:registro.html.twig',
array('form' => $form->createView(),
'errores' => $errors));
}
Form:
->add('fecNacimiento','date', array('widget' => 'single_text',
'format' => 'dd/MM/yyyy',
'invalid_message' => 'Debe introducir una fecha válida',
'label' => 'Fecha nacimiento: '))
I'm getting no errors messages when user puts aninvalid date, for example, 121/05/2000 (dd/mm/yyyy format), but $for->isValid() is returning false. But when user puts 77/05/2000, it's working wrong, inserting a date in database adding 77 days to 01/05/2000.
Where I'm wrong?
Thanks in advance
You could try to solve this adding the 'input' option to the options array:
->add('fecNacimiento','date',
array('widget' => 'single_text',
'format' => 'dd/MM/yyyy',
'invalid_message' => 'Debe introducir una fecha válida',
'label' => 'Fecha nacimiento: ',
'input' => 'datetime' ))
Related
I am designing a module to calculate the VAT between two dates. I already have everything working, it already calculates the VAT perfectly, but now I want it to be displayed on the configuration screen of the module when clicking on save settings. It's the only thing I'm missing. Right now if I want the VAT to be shown I have to exit and re-enter the module configuration screen. Right now where I try to update the VAT field is in the postProcess() function, with this line:Configuration::updateValue($this->name . '_iva', $ivaAcumulado);
<?php
if (!defined('_PS_VERSION_')) {
exit;
}
class moduloResumenIva extends Module {
protected $config_form = false;
public function __construct() {
$this->name = 'moduloResumenIva';
$this->tab = 'administration';
$this->version = '1.0.0';
$this->author = 'luilli';
$this->need_instance = 0;
/**
* Set $this->bootstrap to true if your module is compliant with bootstrap (PrestaShop 1.6)
*/
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('moduloResumenIva');
$this->description = $this->l('mi nuevo modulo mi nuevo modulomi nuevo modulomi nuevo modulomi nuevo modulo');
$this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
}
/**
* Don't forget to create update methods if needed:
* http://doc.prestashop.com/display/PS16/Enabling+the+Auto-Update
*/
public function install() {
Configuration::updateValue('MIMODULOMISMADB_LIVE_MODE', false);
return parent::install() &&
$this->registerHook('header') &&
$this->registerHook('actionPaymentConfirmation') &&
$this->registerHook('backOfficeHeader');
}
public function uninstall() {
Configuration::deleteByName('MIMODULOMISMADB_LIVE_MODE');
return parent::uninstall();
}
/**
* Load the configuration form
*/
public function getContent() {
/**
* If values have been submitted in the form, process.
*/
if (((bool) Tools::isSubmit('submitButton')) == true) {
$this->postProcess();
}
$this->context->smarty->assign('module_dir', $this->_path);
$output = $this->context->smarty->fetch($this->local_path . 'views/templates/admin/configure.tpl');
return $output . $this->renderForm();
}
/**
* Create the form that will be displayed in the configuration of your module.
*/
protected function renderForm() {
$values = array();
$this->fields_form = array();
$this->context->controller->addJqueryUI('ui.datepicker');
$defaultDate = date('Y-m-d');
if (!Configuration::get($this->name . 'my_date_desde')) {
$values['my_date_desde'] = Tools::getValue('my_date_desde', $defaultDate);
} else {
$values['my_date_desde'] = Tools::getValue('my_date_desde', Configuration::get($this->name . '_my_date_desde'));
}
if (!Configuration::get($this->name . 'my_date_hasta')) {
$values['my_date_hasta'] = Tools::getValue('my_date_hasta', $defaultDate);
} else {
$values['my_date_hasta'] = Tools::getValue('my_date_hasta', Configuration::get($this->name . '_my_date_hasta'));
}
$values['iva'] = Tools::getValue('iva', Configuration::get($this->name . '_iva'));
$helper = new HelperForm();
$helper->show_toolbar = false;
$helper->table = $this->table;
$lang = new Language((int) Configuration::get('PS_LANG_DEFAULT'));
$helper->default_form_language = $lang->id;
$helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;
$helper->identifier = $this->identifier;
$helper->submit_action = 'Submit' . $this->name;
$helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false) . '&configure=' . $this->name . '&tab_module=' . $this->tab . '&module_name=' . $this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->tpl_vars = array(
'fields_value' => $values,
'languages' => $this->context->controller->getLanguages(),
'id_language' => $this->context->language->id,
);
return $helper->generateForm(array($this->getConfigForm()));
}
/**
* Create the structure of your form.
*/
protected function getConfigForm() {
return array(
'form' => array(
'legend' => array(
'title' => $this->l('Settings'),
'icon' => 'icon-cogs'
),
'input' => array(
array(
'type' => 'date',
'label' => $this->l('Desde'),
'name' => 'my_date_desde',
'required' => true,
),
array(
'type' => 'date',
'label' => $this->l('Hasta'),
'name' => 'my_date_hasta',
'required' => true,
),
array(
'type' => 'text',
'label' => $this->l('Iva'),
'name' => 'iva',
)
),
'submit' => array(
'title' => $this->l('Save settings'),
'class' => 'button btn btn-default pull-right',
'name' => 'submitButton',
)
),
);
}
/**
* Set values for the inputs.
*/
protected function getConfigFormValues() {
return array(
'CAMPOID' => Configuration::get('CAMPOID', null),
'MIMODULOMISMADB_ACCOUNT_USUARIO' => Configuration::get('MIMODULOMISMADB_ACCOUNT_USUARIO', null),
'MIMODULOMISMADB_ACCOUNT_PASSWORD' => Configuration::get('MIMODULOMISMADB_ACCOUNT_PASSWORD', null),
'my_date_desde' => Configuration::get('my_date_desde', null),
'my_date_hasta' => Configuration::get('my_date_hasta', null),
'iva' => Configuration::get('iva', null),
);
}
/**
* Save form data.
*/
protected function postProcess() {
if (Tools::isSubmit('Submit' . $this->name)) {
if (Tools::getValue('my_date_desde')) {
Configuration::updateValue($this->name . '_my_date_desde', Tools::getValue('my_date_desde'));
}
if (Tools::getValue('my_date_hasta')) {
Configuration::updateValue($this->name . '_my_date_hasta', Tools::getValue('my_date_hasta'));
}
$fechaDesde = Configuration::get($this->name . '_my_date_desde', null) . " 00:00:00";
$fechaHasta = Configuration::get($this->name . '_my_date_hasta', null) . " 00:00:00";
$db = \Db::getInstance();
$sql = "select * from orders where date_add BETWEEN '" . $fechaDesde . "' AND '" . $fechaHasta . "'";
$ivaAcumulado = 0;
$result = $db->executeS($sql);
foreach ($result as $row) {
$ivaAcumulado += $row["total_paid_tax_incl"] - $row["total_paid_tax_excl"];
}
Configuration::updateValue($this->name . '_iva', $ivaAcumulado);
}
}
/**
* Add the CSS & JavaScript files you want to be loaded in the BO.
*/
public function hookBackOfficeHeader() {
if (Tools::getValue('module_name') == $this->name) {
$this->context->controller->addJS($this->_path . 'views/js/back.js');
$this->context->controller->addCSS($this->_path . 'views/css/back.css');
}
}
/**
* Add the CSS & JavaScript files you want to be added on the FO.
*/
public function hookHeader() {
//mail("luilli.guillan#gmail.com", "hola", "viva el vino");
$this->context->controller->addJS($this->_path . '/views/js/front.js');
$this->context->controller->addCSS($this->_path . '/views/css/front.css');
}
}
You can do the redirection after saving the changes:
https://github.com/PrestaShop/contactform/blob/dev/contactform.php#L99
if (((bool) Tools::isSubmit('submitButton')) == true) {
$this->postProcess();
Tools::redirectAdmin($this->context->link->getAdminLink('AdminModules') . '&configure=' . $this->name . '&conf=6');
}
As of now, I see that you don't have any validation, so this solution should be enough.
I would like to set up a cron job and do a scheduled export of orders to a .xlsx file.
I wonder if there is an easy way to set up export of orders in X-Cart 5 using the linux console command?
You can set up the REST API module to obtain orders by conditions
https://devs.x-cart.com/rest-api/
https://devs.x-cart.com/rest-api/cookbook.html
https://devs.x-cart.com/rest-api/v5.4.0.8/Core/Order.html
https://market.x-cart.com/addons/rest-api.html
then use some console HTTP agent
for example wget
wget --header="Content-Type: application/json" --method=GET --no-check-certificate -q -O /tmp/somefile.txt 'https://HOST/src/admin.php?target=RESTAPI&_key=h1cvNg34654ZCSVWpMokqUqI&_path=order'
(optional) after all convert the file
/tmp/somefile.txt to a .xlsx file.
via some offline or online tools
I figured out a little about the X-Cart 5 mechanism and wrote the following solution. I would be glad if this research helps someone else.
Bash script to start export in file:
/path_to_project/script/export.sh
Contains code:
#!/usr/bin/env bash
cd /path_to_project/
iteration=0
is_event_setted=$(php "console.php" --target=export --action=set_event_task $i);
if [ $is_event_setted == 'OK' ] ; then
while [ 1 = 1 ] ; do
(( iteration++ ))
echo $iteration
is_export_not_finished=$(php "console.php" --target=export --action=sh_is_export_not_finished $i);
if [ $is_export_not_finished == 'export_not_finished' ] ; then
echo "Export continues..."
php "console.php" --target=export --action=run_event_task
else
echo "Export was finished."
break
fi
done
fi
Export console controller managing the process in the file:
/path_to_project/classes/XLite/Controller/Console/Export.php
Contains code:
<?php
// vim: set ts=4 sw=4 sts=4 et:
/**
* Copyright (c) 2011-present Qualiteam software Ltd. All rights reserved.
* See https://www.x-cart.com/license-agreement.html for license details.
*/
namespace XLite\Controller\Console;
class Export extends \XLite\Controller\Console\AConsole
{
/**
* Generator
*
* #var \XLite\Logic\Export\Generator
*/
protected $generator;
private $section = [
// 'XLite\Logic\Export\Step\Products',
// 'XLite\Logic\Export\Step\Attributes',
// 'XLite\Logic\Export\Step\AttributeValues\AttributeValueCheckbox',
'XLite\Logic\Export\Step\Orders',
// 'XLite\Logic\Export\Step\Categories',
// 'XLite\Logic\Export\Step\ProductsCustom',
// 'XLite\Logic\Export\Step\Users',
// 'XLite\Module\XC\Reviews\Logic\Export\Step\Reviews',
// 'XLite\Module\XC\NewsletterSubscriptions\Logic\Export\Step\NewsletterSubscribers',
// 'XLite\Module\XC\CustomProductTabs\Logic\Export\Step\CustomTabs',
// 'XLite\Module\XC\CustomProductTabs\Logic\Export\Step\GlobalTabs',
];
private $options = [
'files' => 'local', // 'local', 'url'
'attrs' => 'global', // 'global', 'global_n_classes', 'all', 'none'
'delimiter' => ',',
'charset' => 'UTF-8',
'filter' => '',
'selection' => [],
'type' => 'xlsx', // 'csv', 'xls', 'xlsx'
];
public function getGenerator()
{
if (!isset($this->generator)) {
$state = \XLite\Core\Database::getRepo('XLite\Model\TmpVar')->getEventState($this->getEventName());
$this->generator = $state && isset($state['options']) ? new \XLite\Logic\Export\Generator($state['options']) : false;
}
return $this->generator;
}
protected function doActionTest()
{
exit('Console-export test phrase');
}
/**
* Delete all files
*
* #return void
*/
protected function doActionDeleteFiles()
{
$generator = new \XLite\Logic\Export\Generator();
$generator->deleteAllFiles();
echo "Files were deleted successfully!\n";
}
protected function doActionShIsExportNotFinished()
{
if ($this->isExportNotFinished()) {
exit('export_not_finished');
} else {
exit('export_finished');
}
}
protected function doActionSetEventTask()
{
foreach ($this->options as $key => $value) {
if (
!\XLite\Core\Config::getInstance()->Export
|| \XLite\Core\Config::getInstance()->Export->$key != $value
) {
\XLite\Core\Database::getRepo('XLite\Model\Config')->createOption([
'category' => 'Export',
'name' => $key,
'value' => $value,
]);
}
}
if (in_array('XLite\Logic\Export\Step\AttributeValues\AttributeValueCheckbox', $this->section)) {
$addSections = [
'XLite\Logic\Export\Step\AttributeValues\AttributeValueSelect',
'XLite\Logic\Export\Step\AttributeValues\AttributeValueText',
'XLite\Logic\Export\Step\AttributeValues\AttributeValueHidden',
];
$this->section = array_merge(
$this->section,
$addSections
);
}
\XLite\Logic\Export\Generator::run($this->assembleExportOptions());
exit('OK');
}
protected function doActionRunEventTask()
{
$event = $this->getEventName();
$result = false;
$errors = [];
$task = \XLite\Core\Database::getRepo('XLite\Model\EventTask')->findOneBy(['name' => $event]);
if ($task) {
\XLite\Core\Database::getRepo('XLite\Model\EventTask')->cleanTasks($event, $task->getId());
if (\XLite\Core\EventListener::getInstance()->handle($task->getName(), $task->getArguments())) {
$task = \XLite\Core\Database::getEM()->merge($task);
\XLite\Core\Database::getEM()->remove($task);
$result = true;
}
$errors = \XLite\Core\EventListener::getInstance()->getErrors();
} else {
\XLite\Core\Database::getRepo('XLite\Model\TmpVar')->removeEventState($event);
}
\XLite\Core\Database::getEM()->flush();
$state = \XLite\Core\Database::getRepo('XLite\Model\TmpVar')->getEventState($event);
$this->setPureAction(true);
if ($result && $state) {
$data = [
'percent' => \XLite\Core\Database::getRepo('XLite\Model\TmpVar')->getEventStatePercent($event),
'error' => !empty($errors),
'messages' => $errors
];
if (!empty($state['touchData'])) {
$data += $state['touchData'];
}
\XLite\Core\Event::eventTaskRun($data);
} else {
\XLite\Core\Event::eventTaskRun([
'percent' => 100,
'error' => true,
'messages' => $errors
]);
$result = false;
}
if ($errors) {
foreach ($errors as $message) {
\XLite\Core\TopMessage::addError($message);
}
$result = false;
}
}
/**
* Assemble export options
*
* #return array
*/
protected function assembleExportOptions()
{
return [
'include' => $this->section,
'copyResources' => 'local' == $this->options['files'],
'attrs' => $this->options['attrs'],
'delimiter' => $this->options['delimiter'],
'charset' => $this->options['charset'],
'filter' => $this->options['filter'],
'selection' => $this->options['selection'],
'type' => $this->options['type'],
];
}
/**
* Get event name
*
* #return string
*/
protected function getEventName()
{
return \XLite\Logic\Export\Generator::getEventName();
}
/**
* Get export cancel flag name
*
* #return string
*/
protected function getExportCancelFlagVarName()
{
return \XLite\Logic\Export\Generator::getCancelFlagVarName();
}
/**
* Check - export process is not-finished or not
*
* #return boolean
*/
protected function isExportNotFinished()
{
$state = \XLite\Core\Database::getRepo('XLite\Model\TmpVar')->getEventState($this->getEventName());
return $state
&& in_array($state['state'], [\XLite\Core\EventTask::STATE_STANDBY, \XLite\Core\EventTask::STATE_IN_PROGRESS])
&& !\XLite\Core\Database::getRepo('XLite\Model\TmpVar')->getVar($this->getExportCancelFlagVarName());
}
}
I have a problem with my FormType. I want to display data and thanks to the querybuilder make a distinction. Problem when I call my method with a -> select ('t.nomVern') I have "Warning: spl_object_hash () expects parameter 1 to be object, string given" as an error message.
I do not understand why.
My FormType ObservationType:
<?php
namespace ObservationBundle\Form;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Vich\UploaderBundle\Form\Type\VichImageType;
use ImportBundle\Repository\TaxrefRepository;
use ImportBundle\Entity\Taxref;
class ObservationType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('date', DateType::class, array(
'widget' => 'single_text',
'html5' => false,
'attr' => array(
'placeholder' => 'Choisir la date de l\'observation',
)
))
->add('latitude', TextType::class, array(
'attr' => array(
'placeholder' => 'Latitude ex : 31.85322'
)
))
->add('longitude', TextType::class, array(
'attr' => array(
'placeholder' => 'Longitude ex : 33.55555'
)
))
->add('nombre', IntegerType::class)
->add('imageFile', VichImageType::class, array(
'required' => false,
'allow_delete' => false, // not mandatory, default is true
'download_link' => false, // not mandatory, default is true
'attr' => array(
'placeholder' => 'Votre image'
)
))
->add('valide', HiddenType::class)
->add('commentaire', HiddenType::class)
->add('gpsAffiche', HiddenType::class)
->add('meteo', HiddenType::class)
->add('saison', HiddenType::class)
->add('typeSaisie', HiddenType::class)
->add('precipitation', HiddenType::class)
->add('periode', HiddenType::class)
->add('environnement', HiddenType::class)
->add('sensibilite', HiddenType::class)
->add('comportement', HiddenType::class)
->add('species', EntityType::class, array(
'label' => 'Espèce observée :',
'class' => 'ImportBundle\Entity\Taxref',
'choice_label' => 'nomVern',
'query_builder' => function(TaxrefRepository $qb){
return $qb->distinctTaxref();
}
))
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'ObservationBundle\Entity\Observation'
));
}
/**
* #return string
*/
public function getBlockPrefix()
{
return 'observationbundle_observation';
}
}
And my repository :
<?php
namespace ImportBundle\Repository;
use Doctrine\DBAL\Query\QueryBuilder;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class TaxrefRepository extends EntityRepository
{
/**
* Pagination liste des especes
* #param int $page
* #param int $max
* #return Paginator
*/
public function findByPage($page = 1, $max = 8)
{
if(!is_numeric($page)) {
throw new \InvalidArgumentException(
'$page must be an integer ('.gettype($page).' : '.$page.')'
);
}
if(!is_numeric($page)) {
throw new \InvalidArgumentException(
'$max must be an integer ('.gettype($max).' : '.$max.')'
);
}
$dql = $this->createQueryBuilder('t');
$dql->orderBy('t.id', 'DESC');
$firstResult = ($page - 1) * $max;
$query = $dql->getQuery();
$query->setFirstResult($firstResult);
$query->setMaxResults($max);
$paginator = new Paginator($query);
if(($paginator->count() <= $firstResult) && $page != 1) {
throw new NotFoundHttpException('Page not found');
}
return $paginator;
}
/**
* #return \Doctrine\ORM\QueryBuilder
*/
public function distinctTaxref()
{
return $this
->createQueryBuilder('t')
->select('t.nomVern')
->distinct(true)
->orderBy('t.nomVern', 'ASC');
}
}
Thank you in advance for your help and sorry for my bad english :/
Try this part of code
return $this
->createQueryBuilder('t')
->select(array('t.nomVern'))
->distinct(true)
->orderBy('t.nomVern', 'ASC');
I believe that, since you're using EntityType, Symfony expects to have an array of objects, whereas you select a single column which produces an array of strings.
Can you try selecting an object as a whole:
return $this
->createQueryBuilder('t')
->select('t')
->distinct(true)
->orderBy('t.nomVern', 'ASC');
Does this work?
I am looking solutions for using different categories for main and mobile Magento store view. I have configure mobile store view as new theme with user agent string and exception.
How can I do show one categories on main store view and another one categories on mobile store view. Both store views use by one domain name.
What I will suggest it create an category attribute with dropdown. Following Script will help you to do so :
SQL Setup file :
<?php
$installer = $this;
$installer->startSetup();
$installer->addAttribute("catalog_category", "wheretoshow", array(
"type" => "int",
"backend" => "",
"frontend" => "",
"label" => "Where to Show",
"input" => "select",
"class" => "",
"source" => "modulename/eav_entity_attribute_source_categoryoptions",
"global" => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
"visible" => true,
"required" => false,
"user_defined" => false,
"default" => "Main Website",
"searchable" => false,
"filterable" => false,
"comparable" => false,
"visible_on_front" => false,
"unique" => false,
"note" => ""
));
$installer->endSetup();
Model/Categoryoptions.php
<?php
class class Packagename_Modulename_Model_Eav_Entity_Attribute_Source_Categoryoptions extends Mage_Eav_Model_Entity_Attribute_Source_Abstract
{
/**
* Retrieve all options array
*
* #return array
*/
public function getAllOptions()
{
if (is_null($this->_options)) {
$this->_options = array(
array(
"label" => Mage::helper("eav")->__("Mobile Website"),
"value" => 1
),
array(
"label" => Mage::helper("eav")->__("Main Website"),
"value" => 2
),
);
}
return $this->_options;
}
/**
* Retrieve option array
*
* #return array
*/
public function getOptionArray()
{
$_options = array();
foreach ($this->getAllOptions() as $option) {
$_options[$option["value"]] = $option["label"];
}
return $_options;
}
/**
* Get a text for option value
*
* #param string|integer $value
* #return string
*/
public function getOptionText($value)
{
$options = $this->getAllOptions();
foreach ($options as $option) {
if ($option["value"] == $value) {
return $option["label"];
}
}
return false;
}
/**
* Retrieve Column(s) for Flat
*
* #return array
*/
public function getFlatColums()
{
$columns = array();
$columns[$this->getAttribute()->getAttributeCode()] = array(
"type" => "tinyint(1)",
"unsigned" => false,
"is_null" => true,
"default" => null,
"extra" => null
);
return $columns;
}
/**
* Retrieve Indexes(s) for Flat
*
* #return array
*/
public function getFlatIndexes()
{
$indexes = array();
$index = "IDX_" . strtoupper($this->getAttribute()->getAttributeCode());
$indexes[$index] = array(
"type" => "index",
"fields" => array($this->getAttribute()->getAttributeCode())
);
return $indexes;
}
/**
* Retrieve Select For Flat Attribute update
*
* #param int $store
* #return Varien_Db_Select|null
*/
public function getFlatUpdateSelect($store)
{
return Mage::getResourceModel("eav/entity_attribute")
->getFlatUpdateSelect($this->getAttribute(), $store);
}
}
While Fetching the categories on frontend, filter those by this attribute depending on your website.
I use the following code to load an invoice and send email programatically:
<?php
$invoice = Mage::getModel('sales/order_invoice')
->loadByIncrementId($invoice_queue['increment_id']);
if (null !== $invoice->getId()){
$invoice->sendEmail();
echo "- Done Invoice #". $invoice_queue['increment_id'] ."\r\n";
}
$invoice = null;
?>
This appears to be sending the invoice email correctly. However, the PDF attachment of the invoice isn't there in the email.
If I were to send the email via magento, it works.
Any idea how to get the PDF to be attached, when calling sendEmail() function?
For sending invoice email you need to overwrite
In mage/core/model/email/template.php add this method at the end of the file:
public function addAttachment(Zend_Pdf $pdf){
$file = $pdf->render();
$attachment = $this->getMail()->createAttachment($file);
$attachment->type = 'application/pdf';
$attachment->filename = 'test.pdf';
}
2 In sales/model/order/Invoice.php add the code between comments(2 lines of code) to the function sendEmail like this:
<?php
public function sendEmail($notifyCustomer=true, $comment='')
{
if (!Mage::helper('sales')->canSendNewInvoiceEmail($this->getOrder()->getStore()->getId())) {
return $this;
}
$currentDesign = Mage::getDesign()->setAllGetOld(array(
'package' => Mage::getStoreConfig('design/package/name', $this->getStoreId()),
'store' => $this->getStoreId()
));
$translate = Mage::getSingleton('core/translate');
/* #var $translate Mage_Core_Model_Translate */
$translate->setTranslateInline(false);
$order = $this->getOrder();
$copyTo = $this->_getEmails(self::XML_PATH_EMAIL_COPY_TO);
$copyMethod = Mage::getStoreConfig(self::XML_PATH_EMAIL_COPY_METHOD, $this->getStoreId());
if (!$notifyCustomer && !$copyTo) {
return $this;
}
$paymentBlock = Mage::helper('payment')->getInfoBlock($order->getPayment())
->setIsSecureMode(true);
$mailTemplate = Mage::getModel('core/email_template');
if ($order->getCustomerIsGuest()) {
$template = Mage::getStoreConfig(self::XML_PATH_EMAIL_GUEST_TEMPLATE, $order->getStoreId());
$customerName = $order->getBillingAddress()->getName();
} else {
$template = Mage::getStoreConfig(self::XML_PATH_EMAIL_TEMPLATE, $order->getStoreId());
$customerName = $order->getCustomerName();
}
// attachment here
$pdf = Mage::getModel('sales/order_pdf_invoice')->getPdf(array($this));
$mailTemplate->addAttachment($pdf);
if ($notifyCustomer) {
$sendTo[] = array(
'name' => $customerName,
'email' => $order->getCustomerEmail()
);
if ($copyTo && $copyMethod == 'bcc') {
foreach ($copyTo as $email) {
$mailTemplate->addBcc($email);
}
}
// enter code here
}
if ($copyTo && ($copyMethod == 'copy' || !$notifyCustomer)) {
foreach ($copyTo as $email) {
$sendTo[] = array(
'name' => null,
'email' => $email
);
}
}
foreach ($sendTo as $recipient) {
$mailTemplate->setDesignConfig(array('area'=>'frontend', 'store'=>$order->getStoreId()))
->sendTransactional(
$template,
Mage::getStoreConfig(self::XML_PATH_EMAIL_IDENTITY, $order->getStoreId()),
$recipient['email'],
$recipient['name'],
array(
'order' => $order,
'invoice' => $this,
'comment' => $comment,
'billing' => $order->getBillingAddress(),
'payment_html'=> $paymentBlock->toHtml(),
)
);
}
$translate->setTranslateInline(true);
Mage::getDesign()->setAllGetOld($currentDesign);
return $this;
} ?>
Now when you create an invoice from the back office and you select to notify customer a pdf attachment should be sent as well.