CodeIgniter form validation multilanguage labels - codeigniter

I'm currently working on a website that can be viewed in 3 different languages. I've put all text into languages files and almost everything is working as expected.
Things like configuration for pagination I've put into a configuration file and into application/config, like this:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
$config['num_links'] = 2;
$config['full_tag_open'] = '<p class="pagination">';
$config['full_tag_close'] = '</p>';
$config['first_link'] = '« ' . lang('first');
$config['last_link'] = lang('last') . ' »';
And it works great, but I've tried the same for my form validation configuration file, like this:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
$config = array(
'login' => array(
array(
'field' => 'login_email',
'label' => lang('emailaddress'),
'rules' => 'trim|required|valid_email|min_length[6]'
),
array(
'field' => 'login_password',
'label' => lang('password'),
'rules' => 'trim|required'
),
),
But this doesn't seem to work. It looks like this configuration file gets loaded before the language files/library.
And to be honest, at the moment I don't really have an idea how to fix this other than taking everything out of the configuration file again, and put it into the controller, but I'd rather not do this.
Any ideas how to fix this?

if you check how field translation is done when defining form validation rules (see example below and consider the second argument):
$this->form_validation->set_rules('first_name', 'lang:first_name', 'required');
you can see where you are doing wrong in your actual code.
instead of:
array(
'field' => 'login_password',
'label' => lang('password'),
'rules' => 'trim|required'
),
the way to go is:
array(
'field' => 'login_password',
'label' => 'lang:password',
'rules' => 'trim|required'
),

#Krishna Raj K
i use a trans function like you. And i have fixed it.
one more thing that i use wiredesignz hmvc.
MY_Form_validation.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/** application/libraries/MY_Form_validation **/
class MY_Form_validation extends CI_Form_validation
{
public $CI;
protected function _translate_fieldname($fieldname)
{
// Do we need to translate the field name? We look for the prefix 'trans:' to determine this
if (sscanf($fieldname, 'trans:%s', $line) === 1 )
{
return trans($line);
}
return $fieldname;
}
}
rules in model
'parent_id' => array(
'field'=>'parent_id',
'label'=>'trans:main.taxonomy.column.parent_id.name',
'rules'=>'is_natural_no_zero',
),
and in controller, you must load according to this order
//helper
$this->load->helper(array('array','form','anhtocon','trans'));
//library
$this->load->library(array('Nested_set','form_validation'));
$this->form_validation->CI =& $this;
//model
$this->load->model('taxonomy_model');

Related

Customizing Woocommerce reports time interval

I need to insert a last4Days option in the reports tab.
I've done that by changing the original files but WooCommerce keeps changing to the original after a while.
So I tried to find a filter to do so, but I'm not finding it.
Unfortunately the Woo team did not do the user-friendly thing and include a filter on the report-length arguments. Short of some meta-programming magic (like dynamically over-writing the arguments in the .php file's text before load, very dangerous) the only way I can see is to go up the instantiation ladder to the point where the report is generated, and then have it call a custom class based on the one you are you using. Luckily WooCommerce does provide a filter for the path to the report file, it's in wc-class-admin-reports.php and the hook is called wc_admin_reports_path. If we were extending the coupon usage report, it would look a little something like:
add_filter('wc_admin_reports_path', 'redirect_coupon_report_class_path', 10, 2);
function redirect_coupon_report_class_path($path, $report_name, $class) {
if($report_name == 'coupon-usage') {
$path = 'path/to/my/custom/class.php';
}
return $path;
}
What you'll need to do is copy the class of the report you're trying to alter, and paste it somewhere in your theme or plugin. Then, add a filter calling a function that will check to see if the report being passed in is the one you want to modify, and redirect it to your custom class. Within your custom class, you can do pretty much whatever you want, but as with any override you'll want to see what they change in that file with each update. You can extend the class like so:
class WC_Report_Coupon_Usage_Custom extends WC_Report_Coupon_Usage {
// Call the parent constructor
function __construct() {
parent::__construct();
}
// Add a method that you would have previously overwritten directly in the plugin file
public function output_report() {
$ranges = array(
'year' => __( 'Year', 'woocommerce' ),
'last_month' => __( 'Last Month', 'woocommerce' ),
'month' => __( 'This Month', 'woocommerce' ),
'7day' => __( 'Last 7 Days', 'woocommerce' ),
'4day' => __( 'Last 4 Days', 'woocommerce' )
);
$this->chart_colours = array(
'discount_amount' => '#3498db',
'coupon_count' => '#d4d9dc',
);
$current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day';
if ( ! in_array( $current_range, array( 'custom', 'year', 'last_month', 'month', '7day' ) ) ) {
$current_range = '7day';
}
$this->calculate_current_range( $current_range );
include( WC()->plugin_path() . '/includes/admin/views/html-report-by-date.php');
}
}

How to display customer email in orders.csv

can someone help me? how can I add a new field in orders.csv file in Mangento? for example i want to have in csv file email and phone.
please click the link below to understand which export is talking about
http://i.stack.imgur.com/fBAHG.png
Thank you
You have to customize the Grid block : /app/code/core/Mage/Adminhtml/Block/Sales/Order/Grid.php
So You can do like this. If you already enabled the local module functionality, Please copy and paste it to this path /app/code/local/Mage/Adminhtml/Block/Sales/Order/Grid.php
And Open that new file ( pasted ), check this method _prepareColumns().
In this method, you have to add those attributes which you are gonna to export in order.csv.
Check the following:
....
$this->addColumn('customer_email', array(
'header' => Mage::helper('sales')->__('Email'),
'index' => 'customer_email',
));
....
After this, refresh the magento cache.
Please check the following code:
In Grid.php
protected function _prepareCollection()
{
$collection = Mage::getResourceModel($this->_getCollectionClass());
$collection->getSelect()
->join(
'customer_entity',
'main_table.customer_id = customer_entity.entity_id', array('customer_email' => 'email')
);
$this->setCollection($collection);
return parent::_prepareCollection();
}
Then in protected function _prepareColumns() function add following code:
$this->addColumn('customer_email', array(
'header' => Mage::helper('sales')->__('Email'),
'index' => 'customer_email',
));
After this, you must refresh the cache or login again.

How to translate form labels in Zend Framework 2?

I'm not getting it!.. Can please someone explain, how to translate form labels? A simple example would be great.
Thank you in advance!
class Search\Form\CourseSearchForm
...
class CourseSearchForm extends Form {
...
public function __construct(array $cities) {
parent::__construct('courseSearch');
...
$this->add(array(
'name' => 'city',
'type' => 'Zend\Form\Element\Select',
'options' => array(
'label' => 'Stadt',
'value_options' => $this->cities,
'id' => 'searchFormCity',
),
));
...
}
}
view script /module/Search/view/search/search/search-form.phtml
<?php echo $this->form()->openTag($form); ?>
<dl>
...
<dt><label><?php echo $form->get('city')->getLabel(); ?></label></dt>
<dd><?php echo $this->formRow($form->get('city'), null, false, false); ?></dd>
...
</dl>
<?php echo $this->form()->closeTag(); ?>
<!-- The formRow(...) is my MyNamespace\Form\View\Helper (extends Zend\Form\View\Helper\FormRow); the fourth argument of it disables the label. -->
The module/Application/config/module.config.php is configured:
return array(
'router' => ...
'service_manager' => array(
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
),
),
'translator' => array(
'locale' => 'de_DE',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
'controllers' => ...
'view_manager' => ...
);
I also edited my view and use the FormLabel view helper:
<dt><label><?php echo $this->formLabel($form->get('city')); ?></label></dt>
Furthermore I debugged the FormLabel at the place, where the tranlator is used (lines 116-120) -- seems to be OK.
But it's still not working.
EDIT
The (test) items for labels, I added to the de_DE.po file manually, are tranlated. The ZF2 side problem was actually, that I was using $form->get('city')->getLabel() instead of $this->formlabel($form->get('city')) in th view script.
The problem is now, that the labels are not added to the de_DE.po file. But it's not a ZF2 issue anymore, so I've accept Ruben's answer and open a new Poedit question.
Instead of using:
<?php echo $form->get('city')->getLabel(); ?>
You should use the formlabel view helper. This helper automatically uses your translator during rendering if you have inserted it in your ServiceManager. Most likely you will have it in your Application's module module.config.php:
'service_manager' => array(
'factories' => array(
'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
),
),
'translator' => array(
'locale' => 'en_US',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
Once you do use the formlabel view helper:
echo $this->formLabel($form->get('city'));
And of course make sure your translations are in your .po file.
i think your problem is that you label are not detected by poedit (or similar tool), so you have to add them manually to your poedit catalogs (.po)
to make your label strings detected by tools like poedit, your strings need to be used inside a translate() function or _() (other function can be added in Catalog/properties/sources keyword)
as the _() function is not user in ZF2 (today) so a tiny hack is to add a function like this in your index.php (no need to modify anything, this way, in poedit params):
// in index.php
function _($str)
{
return $str;
}
and in your code, just use it when your strings are outside of a translate function
//...
$this->add(array(
'name' => 'city',
'type' => 'Zend\Form\Element\Select',
'options' => array(
'label' => _('myLabel') , // <------ will be detected by poedit
'value_options' => $this->cities,
'id' => 'searchFormCity',
),
));
//...
or like this if you prefer
$myLabel = _('any label string'); // <--- added to poedit catalog
//...
'options' => array(
'label' => $myLabel ,
'value_options' => $this->cities,
'id' => 'searchFormCity',
),
#Ruben says right!
Me I use PoEdit to generate my *.mo files and to be sure to get all translations in the file, I create somewhere (in view for example) a file named _lan.phtml with all text to be translated :
<?php echo $this->translate("My label");
... ?>
Of course, Poedit has to be configured to find my keywords. check this to how to configure it
All solutions don't use the power of ZF2. You must configure your poedit correctly :
All things are here :
http://circlical.com/blog/2013/11/5/localizing-your-twig-using-zend-framework-2-applications

filter and CActiveDataProvider in CGridView

I have these code in index action of controller:
public function actionIndex()
{
$cid = #$_GET['cid'];
$country = Country::model()->findByPk($cid);
if($cid)
$dataProvider=new CActiveDataProvider('City', array(
'criteria'=>array(
'condition'=>'ci_co_id ='.$cid,
),
));
else
$dataProvider=new CActiveDataProvider('City');
$this->render('index',array(
'dataProvider'=>$dataProvider,
'country' => $country
));
}
and these in view/index.php file:
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'city-grid',
'dataProvider'=>$dataProvider,
'filter' => $dataProvider,
'columns'=>array(
array(
'name' => ' ',
'value' => '$row + 1',
),
'ci_name',
'ci_pcode',
array(
'class'=>'CButtonColumn',
),
)
));
?>
but Yii gives me this error:
CActiveDataProvider and its behaviors do not have a method or closure named "getValidators".
What is the problem?
The filter has to be a class that extends CModel. However, you don't seem to be doing any actual filtering, so you can just comment the filter line of your CGridView out.
As a side note, you have major security hole in your criteria. You are leaving yourself wide open to an SQL injection attack.
Specify your criteria as follows to let the database handler properly escape the input:
'criteria'=>array(
'condition'=>'ci_co_id =:cid',
'params'=>array(':cid'=>$cid),
),

In my cakephp controller I keep repeating logic in every function for view code

I have a number of functions in my controller logic and for every one I have some logic that pulls data for a "featured" set of units. These units are on several pages. How do I go about making this one piece of logic available to all 4 of the views that need it?
For reference, here is part of my controller logic:
public function index() {
$this->set('title', 'All accommodations available in and near Gulf Shores, AL');
$this->Unit->Behaviors->attach('Containable');
$this->Unit->contain(
array(
'User'=>array(
'id'),
'Location',
'Complex'=>array('location_id'),
'Image'=>array(
'logo','img1'
)
)
);
$c=$this->Unit->find('all',
array(
'limit'=>3,
'conditions'=>array(
'active'=>1,
'featured'=>1
)
)
);
$this->set('featured', $c);
$this->paginate['Unit']=array(
'limit'=>9,
'order' => 'RAND()',
'contain'=>array(
'User'=>array('email'),
'Complex'=>array('location_id','complex_website'),
'Location',
'Image'
),
'conditions'=>array(
'Unit.active'=>1)
);
$data = $this->paginate('Unit');
$this->set('allaccommodations', $data);
}
public function houses() {
$this->set('title', 'Home rentals available in Gulf Shores');
$this->Unit->Behaviors->attach('Containable');
$this->Unit->contain(
array(
'User'=>array(
'id'),
'Location',
'Complex'=>array('location_id'),
'Image'=>array(
'logo','img1'
)
)
);
$c=$this->Unit->find('all',
array(
'limit'=>3,
'conditions'=>array(
'active'=>1,
'featured'=>1
)
)
);
$this->set('featured', $c);
$this->paginate['Unit']=array(
'limit'=>9,
'order' => 'RAND()',
'contain'=>array(
'User'=>array('email'),
'Location',
'Image'
),
'conditions'=>array(
'Unit.type'=>array('house', 'rentalco'),
'Unit.active'=>1)
);
$data = $this->paginate('Unit');
$this->set('allhouses', $data);
}
...
I have two other functions that set a 'featured' variable that is available to the view. I'm sure there is a much better/more efficient way to do this?
Yes, the idea is to have all the data interaction in your model and have your controller clear and easy to follow. Fat models, skinny controllers. There are custom finds you can use: http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#creating-custom-find-types
but I prefer to just make a model function because they're easier to work with in the IDE with code completion and documentation. So for the featured find you keep using you could do something in your Unit model like:
public function getFeatured($limit) {
$results = $this->find('all', array(
'limit' => $limit,
'conditions' => array(
'active' => 1,
'featured' => 1
)
)
);
return $results;
}
Then in the UnitController:
$this->set('featured', $this->Unit->getFeatured(3));

Resources