I used zf2 authentication for authenticate user in my project.I saved Harib in my user table as user name but if i use my user name Harib then its accept or if i use harib then its not accept,i want to remove case sensitivity of user name so both Harib or harib access how i fix this?
Here is my code:
public function loginAction()
{
$this->layout('layout/login-layout.phtml');
$login_error = false;
$loginForm = new LoginForm();
$form_elements = json_encode($loginForm->form_elements);
if ($this->request->isPost()) {
$post = $this->request->getPost();
$loginForm->setData($post);
if ($loginForm->isValid()) {
$hashed_string = '';
if(
array_key_exists('hashed_input' , $post) &&
$post['hashed_input'] != '' &&
strpos(urldecode($this->params('redirect')) , 'programdetailrequest') !== false
) {
$hashed_string = $post['hashed_input'];
}
$data = $loginForm->getData();
$authService = $this->getServiceLocator()->get('doctrine.authenticationservice.odm_default');
$adapter = $authService->getAdapter();
$adapter->setIdentityValue($data['username']);
$adapter->setCredentialValue(md5($data['password']));
$authResult = $authService->authenticate();
if($authResult->isValid()){
$identity = $authResult->getIdentity();
if( is_object($identity) && method_exists($identity, 'getData') ){
$user_data = $identity->getData();
$authService->getStorage()->write($identity);
// for remeber checkbox
if ($post['rememberme']) {
$token = new UserToken();
$dm = $this->getServiceLocator()->get('doctrine.documentmanager.odm_default');
//if same user already running from other browser then remove previous token.
$check_token = $dm->getRepository('Admin\Document\UserToken')->findOneBy(array( "user_id.id" => $user_data['id'] ));
if (is_object($check_token) && !is_null($check_token)) {
$remove_token = $dm->createQueryBuilder('Admin\Document\UserToken')
->remove()
->field('id')->equals($check_token->id)
->getQuery()->execute();
}
//create token
$user = $dm->getRepository('Admin\Document\User')->findOneBy(array( "id" => $user_data['id'] ));
$token->setProperty('user_id', $user);
$token->setProperty('dataentered', new \MongoDate());
$dm->persist($token);
$dm->flush($token);
//create cookie
if(is_object($token) && property_exists($token, 'id')){
$time = time() + (60 * 60 * 24 * 30); // 1 month
setcookie('token', $token->getProperty('id'), $time, '/');
}
}
if ($user_data['user_type'] == 'onlinemarketer') {
$this->redirect()->toRoute('admin_program_meta');
} elseif ($user_data['user_type'] == 'bucharestofficemanager') {
$this->redirect()->toRoute('admin_program_detail_request');
} else {
if ($this->params('redirect') && urldecode($this->params('redirect')) !== '/logout/') {
$server_url = $this->getRequest()->getUri()->getScheme() . '://' . $this->getRequest()->getUri()->getHost().urldecode($this->params('redirect') . $hashed_string);
return $this->redirect()->toUrl($server_url);
}
return $this->redirect()->toRoute('admin_index');
}
}
} else {
$identity = false;
$login_error = true;
}
}
}
return new ViewModel(array(
'loginForm' => $loginForm,
'form_elements' =>$form_elements,
'login_error' => $login_error,
));
}
and here is my login form code:
<?php
namespace Admin\Form;
use Zend\Form\Form;
use Zend\Form\Element;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\Factory as InputFactory;
class LoginForm extends Form implements InputFilterAwareInterface
{
protected $inputFilter;
public $form_elements = array(
array(
'name' => 'username',
'attributes' => array(
'id' => 'username',
'type' => 'text',
'error_msg' => 'Enter Valid Username',
'data-parsley-required' => 'true',
'data-parsley-pattern' => '^[a-zA-Z0-9_\.\-]{1,50}$',
'data-parsley-trigger' => 'change'
),
'options' => array(
'label' => 'User Name'
),
'validation' => array(
'required'=>true,
'filters'=> array(
array('name'=>'StripTags'),
array('name'=>'StringTrim')
),
'validators'=>array(
array('name'=>'Regex',
'options'=> array(
'pattern' => '/^[a-z0-9_.-]{1,50}+$/', // contain only a to z 0 to 9 underscore, hypen and space, min 1 max 50
'pattern_js' => '^[a-zA-Z0-9_\.\-]{1,50}$'
)
)
)
)
),
array(
'name' => 'password',
'attributes' => array(
'id' => 'password',
'type' => 'password',
'error_msg' => 'Enter Valid Password',
'data-parsley-required' => 'true',
'data-parsley-pattern' => '^[a-zA-Z0-9_\.\-]{6,25}$',
'data-parsley-trigger' => 'change'
),
'options' => array(
'label' => 'Password'
),
'validation' => array(
'required' => true,
'filters'=> array(
array('name'=>'StripTags'),
array('name'=>'StringTrim')
),
'validators'=>array(
array('name'=>'Regex',
'options'=> array(
'pattern' => '/^[a-z0-9_.-]{6,25}+$/', // contain only a to z 0 to 9 underscore, hypen and space, min 1 max 50
'pattern_js' => '^[a-zA-Z0-9_\.\-]{6,25}$'
)
)
)
)
),
array(
'name' => 'hashed_input',
'attributes' => array(
'type' => 'hidden',
'id' => 'hashed_input',
'value' => ''
)
),
array(
'name' => 'rememberme',
'attributes' => array(
'value' => 1,
'id' => 'rememberme',
'type' => 'Checkbox'
),
'options' => array(
'label' => 'Remember Me',
'use_hidden_element' => false,
)
),
array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Log in',
'id' => 'submitbutton'
)
)
);
public function __construct()
{
parent::__construct('user');
$this->setAttribute('method', 'post');
$this->setAttribute('data-parsley-validate', '');
$this->setAttribute('data-elements', json_encode($this->form_elements));
$this->setAttribute('autocomplete', 'off');
for($i=0;$i<count($this->form_elements);$i++){
$elements=$this->form_elements[$i];
$this->add($elements);
}
}
public function getInputFilter($action=false)
{
if(!$this->inputFilter){
$inputFilter = new InputFilter();
$factory = new InputFactory();
for($i=0;$i<count($this->form_elements);$i++){
if(array_key_exists('validation',$this->form_elements[$i])){
$this->form_elements[$i]['validation']['name']=$this->form_elements[$i]['name'];
$inputFilter->add($factory->createInput( $this->form_elements[$i]['validation'] ));
}
}
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
}
how we remove case sensitivity of user name so both Harib or harib accepted?
Add a filter StringToLower in your loginform on the element user_id.
For this, the class that defines your loginform must implement InputFilterProviderInterface and you must add in the getInputFilterSpecification method as follows :
public function getInputFilterSpecification()
{
return [
'username' => [
'name' => 'username',
'required' => true,
'filters' => [
'name' => 'StringToLower',
'name'=>'StripTags',
'name'=>'StringTrim'
],
validators => [
[
'name'=>'Regex',
'options'=> [
'pattern' => '/^[a-z0-9_.-]{1,50}+$/',
'pattern_js' => '^[a-zA-Z0-9_\.\-]{1,50}$'
]
]
]
],
'password' => [
'name' => 'password',
'required' => true,
'filters' => [
array('name'=>'StripTags'),
array('name'=>'StringTrim')
],
'validators' => [
[
'name'=>'Regex',
'options'=> [
'pattern' => '/^[a-z0-9_.-]{6,25}+$/',
'pattern_js' => '^[a-zA-Z0-9_\.\-]{6,25}$'
]
]
]
]
];
}
So you are assured that the value returned in the post is in lowercase.
Since you're using MongoDB, you could use a regex to get the user name from the database.
Suggestion 1:
In your example that would be:
db.stuff.find( { foo: /^bar$/i } );
Suggestion 2:
You can Use $options => i for case insensitive search. Giving some possible examples required for string match.
Exact case insensitive string
db.collection.find({name:{'$regex' : '^string$', '$options' : 'i'}})
Contains string
db.collection.find({name:{'$regex' : 'string', '$options' : 'i'}})
Start with string
db.collection.find({name:{'$regex' : '^string', '$options' : 'i'}})
End with string
db.collection.find({name:{'$regex' : 'string$', '$options' : 'i'}})
Doesn't Contains string
db.collection.find({name:{'$regex' : '^((?!string).)*$', '$options' : 'i'}})
More about regex in MongoDb here: https://docs.mongodb.com/manual/reference/operator/query/regex/index.html
You may do this in two ways. Either you may create a custom authentication adapter or override a method of the default authentication adapter. I recommend that override that method which is easier than creating custom adapter.
So here is the method CredentialTreatmentAdapter::authenticateCreateSelect(). If you look up around 94 line (of zf 2.5) of that method from zend-authentication component then you would find the following line.
$dbSelect->from($this->tableName)
->columns(['*', $credentialExpression])
// See the making of where clause
->where(new SqlOp($this->identityColumn, '=', $this->identity));
Here we are going to make our changes. Now lets override that method by extending Zend\Authentication\Adapter\DbTable. We would make a where clause which would search for both Harib or harib therefore. See the following extended CustomDbTable::class.
<?php
namespace Define\Your\Own\Namespace;
use Zend\Authentication\Adapter\DbTable;
class CustomDbTable extends DbTable
{
protected function authenticateCreateSelect()
{
// build credential expression
if (empty($this->credentialTreatment) || (strpos($this->credentialTreatment, '?') === false)) {
$this->credentialTreatment = '?';
}
$credentialExpression = new SqlExpr(
'(CASE WHEN ?' . ' = ' . $this->credentialTreatment . ' THEN 1 ELSE 0 END) AS ?',
array($this->credentialColumn, $this->credential, 'zend_auth_credential_match'),
array(SqlExpr::TYPE_IDENTIFIER, SqlExpr::TYPE_VALUE, SqlExpr::TYPE_IDENTIFIER)
);
// Here is the catch
$where = new \Zend\Db\Sql\Where();
$where->nest()
->equalTo($this->identityColumn, $this->identity)
->or
->equalTo($this->identityColumn, strtolower($this->identity))
->unnest();
// get select
$dbSelect = clone $this->getDbSelect();
$dbSelect->from($this->tableName)
->columns(array('*', $credentialExpression))
->where($where); // Here we are making our own where clause
return $dbSelect;
}
}
Now custom authentication adapter is ready. You need to use this one inside the factory for authentication service instead of Zend\Authentication\Adapter\DbTable as follows
'factories' => array(
// Auth service
'AuthService' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
// Use CustomDbTable instead of DbTable here
$customDbTable = new CustomDbTable($dbAdapter, 'tableName', 'usernameColumn', 'passwordColumn', 'MD5(?)');
$authService = new AuthenticationService();
$authService->setAdapter($customDbTable);
return $authService;
},
),
All are now set. That overridden method should be called whenever you call this one in your controller method:
$authResult = $authService->authenticate();
This is not tested. So you may need to change things where you need. Please fix those if needed.
Hope this would help you!
Related
I am a Magento beginner so please bear with me...
I am creating a simple extension for my site to add a custom field to my Tags in adminhtml. The custom field is just a number which I need to identify a specific Z-block (cms block extension) so that I can access it as a widget and show it on the frontend in the Tag "category".
I have created a custom module which is working: I set a field in the form using $fieldset and have extended TagController.php, both of which are being used (I made a simple trial to see whether or not they had been recognized). However, I do not know how to go about saving my custom field to DB (whether amending saveAction is enough, and I haven't done it properly, or if I need to add a custom Model or sql install).
Sorry for the "basic" question but I'm new at this, and have mostly done frontend dev (so my extension knowledge is simply limited).
Thank you to anyone who can help...
Claudia
NEW TAG FORM:
public function __construct()
{
parent::__construct();
$this->setId('tag_form');
$this->setTitle(Mage::helper('tag')->__('Block Information'));
}
/**
* Prepare form
*
* #return Mage_Adminhtml_Block_Widget_Form
*/
protected function _prepareForm()
{
$model = Mage::registry('tag_tag');
$form = new Varien_Data_Form(
array('id' => 'edit_form', 'action' => $this->getData('action'), 'method' => 'post')
);
$fieldset = $form->addFieldset('base_fieldset',
array('legend'=>Mage::helper('tag')->__('General Information')));
if ($model->getTagId()) {
$fieldset->addField('tag_id', 'hidden', array(
'name' => 'tag_id',
));
}
$fieldset->addField('form_key', 'hidden', array(
'name' => 'form_key',
'value' => Mage::getSingleton('core/session')->getFormKey(),
));
$fieldset->addField('store_id', 'hidden', array(
'name' => 'store_id',
'value' => (int)$this->getRequest()->getParam('store')
));
$fieldset->addField('name', 'text', array(
'name' => 'tag_name',
'label' => Mage::helper('tag')->__('Tag Name'),
'title' => Mage::helper('tag')->__('Tag Name'),
'required' => true,
'after_element_html' => ' ' . Mage::helper('adminhtml')->__('[GLOBAL]'),
));
$fieldset->addField('zblock', 'text', array(
'name' => 'zblock_id',
'label' => Mage::helper('tag')->__('Z-Block Id'),
'title' => Mage::helper('tag')->__('Z-Block Id'),
'required' => true,
'after_element_html' => ' ' . Mage::helper('adminhtml')->__('[GLOBAL]'),
));
$fieldset->addField('status', 'select', array(
'label' => Mage::helper('tag')->__('Status'),
'title' => Mage::helper('tag')->__('Status'),
'name' => 'tag_status',
'required' => true,
'options' => array(
Mage_Tag_Model_Tag::STATUS_DISABLED => Mage::helper('tag')->__('Disabled'),
Mage_Tag_Model_Tag::STATUS_PENDING => Mage::helper('tag')->__('Pending'),
Mage_Tag_Model_Tag::STATUS_APPROVED => Mage::helper('tag')->__('Approved'),
),
'after_element_html' => ' ' . Mage::helper('adminhtml')->__('[GLOBAL]'),
));
$fieldset->addField('base_popularity', 'text', array(
'name' => 'base_popularity',
'label' => Mage::helper('tag')->__('Base Popularity'),
'title' => Mage::helper('tag')->__('Base Popularity'),
'after_element_html' => ' ' . Mage::helper('tag')->__('[STORE VIEW]'),
));
if (!$model->getId() && !Mage::getSingleton('adminhtml/session')->getTagData() ) {
$model->setStatus(Mage_Tag_Model_Tag::STATUS_APPROVED);
}
if ( Mage::getSingleton('adminhtml/session')->getTagData() ) {
$form->addValues(Mage::getSingleton('adminhtml/session')->getTagData());
Mage::getSingleton('adminhtml/session')->setTagData(null);
} else {
$form->addValues($model->getData());
}
$this->setForm($form);
return parent::_prepareForm();
}
NEW CONTROLLER:
public function saveAction()
{
if ($postData = $this->getRequest()->getPost()) {
if (isset($postData['tag_id'])) {
$data['tag_id'] = $postData['tag_id'];
}
$data['name'] = trim($postData['tag_name']);
$data['zblock'] = $postData['zblock_id'];
$data['status'] = $postData['tag_status'];
$data['base_popularity'] = (isset($postData['base_popularity'])) ? $postData['base_popularity'] : 0;
$data['store'] = $postData['store_id'];
if (!$model = $this->_initTag()) {
Mage::getSingleton('adminhtml/session')->addError(Mage::helper('adminhtml')->__('Wrong tag was specified.'));
return $this->_redirect('*/*/index', array('store' => $data['store']));
}
$model->addData($data);
if (isset($postData['tag_assigned_products'])) {
$productIds = Mage::helper('adminhtml/js')->decodeGridSerializedInput(
$postData['tag_assigned_products']
);
$model->setData('tag_assigned_products', $productIds);
}
try {
$model->save();
Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('The tag has been saved.'));
Mage::getSingleton('adminhtml/session')->setTagData(false);
if (($continue = $this->getRequest()->getParam('continue'))) {
return $this->_redirect('*/tag/edit', array('tag_id' => $model->getId(), 'store' => $model->getStoreId(), 'ret' => $continue));
} else {
return $this->_redirect('*/tag/' . $this->getRequest()->getParam('ret', 'index'));
}
} catch (Exception $e) {
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
Mage::getSingleton('adminhtml/session')->setTagData($data);
return $this->_redirect('*/*/edit', array('tag_id' => $model->getId(), 'store' => $model->getStoreId()));
}
}
return $this->_redirect('*/tag/index', array('_current' => true));
}
The custom field I'm trying to add is "zblock"...thanks and, again, bear with me! :)
First add the field in database table.
For example if you want to add in your custom table.
ALTER TABLE myCustomModuleTable ADD COLUMN 'myCustomField' int(10);
Thenafter, In your controller action take the model object of that table and set the field.
If you are adding data in existing table row:
$value = 6;
$rowInWhichIWantToSave = Mage:getModel('companyname/modulename')->load($rowId);
$rowInWhichIWantToSave->setData('myCustomField',$value)->save();
If you are adding a new row:
$value = 6;
$rowInWhichIWantToSave = Mage:getModel('companyname/modulename');
$rowInWhichIWantToSave->setData('myCustomField',$value)->save();
Hope this helps!!
Im Using
PHP language , yii-1.1.13 framework and MySQL DB.
Views code of Main Page.
<?php
/**
* The view for the trip schedules page.
* #uses ManageTripSchedulesForm $model
* #uses VoyageServiceClassInfo $voyageServiceClassInfo
* #uses LocationInfo $locationInfo
* #uses PierInfo $pierInfo
* #uses VesselInfo $vesselInfo
* #uses ServiceClassInfo $serviceClassInfo
* #uses FareSetInfo $fareSetInfo
* #uses SearchTripsForm $searchTripsForm
* #uses FerryOperatorInfo $ferryOperatorInfo
* #uses ManageTripSchedulesFilterForm $filterForm
*/
$this->setPageTitle(SystemConstants::SITE_NAME . ' - Trip Schedules');
$baseUrl = Yii::app()->getBaseUrl();
$cs = Yii::app()->getClientScript();
// --- POS_HEAD
// a plug-in used in manageTripSchedules.js
$cs->registerScriptFile($baseUrl . '/js/jquery.blockUI.js', CClientScript::POS_HEAD);
// for this view
$cs->registerCssFile($baseUrl . '/css/manageTripSchedules.css');
$cs->registerScriptFile($baseUrl . '/js/manageTripSchedules.js', CClientScript::POS_HEAD);
$this->endWidget('zii.widgets.jui.CJuiDialog');
/**
* Maintenance Dialog widget
*/
$this->beginWidget('zii.widgets.jui.CJuiDialog',array(
'id'=>'dialog',
'options' => array(
'title' => 'Trip Schedules',
'autoOpen' => false,
'modal' => true,
'resizable' => false,
'width' => 600,
'dialogClass' => 'tripschedules-dialog-class',
'show'=>array(
'effect'=>'drop',
'duration'=>500,
),
'hide'=>array(
'effect'=>'drop',
'duration'=>500,
),
),
));
/**
* Render the maintenance dialog view.
*/
echo $this->renderPartial('manageTripSchedulesDialog', array(
'model' => $model,
'ferryOperatorInfo' => $ferryOperatorInfo,
'locationInfo' => $locationInfo,
'pierInfo' => $pierInfo,
'vesselInfo' => $vesselInfo,
'serviceClassInfo' => $serviceClassInfo,
'fareSetInfo' => $fareSetInfo
));
$this->endWidget('zii.widgets.jui.CJuiDialog');
<div id="grid-container" class="grid-div">
<?php
$pageSize = 10;
$helper = new TripSchedulesGridHelper($this);
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'tripschedules-grid',
'dataProvider' => $voyageServiceClassInfo->searchTripSchedules(Yii::app()->user->ferry_operator_id, $filterForm, $pageSize),
'emptyText' => 'No data found.',
'selectableRows' => 0,
'template' => '{items}{pager}', // to remove summary header
'pager' => array(
'header' => '', // to remove 'Go to page:'
),
'cssFile' => $baseUrl . '/css/manageTripSchedulesGrid.css',
'columns' => array(
array(
'name' => 'id',
'value' => '$data->voyage_service_class_id',
'headerHtmlOptions' => array('style' => 'display:none'),
'htmlOptions' => array('style' => 'display:none'),
),
'voyage.ferry_operator.name::Operator',
array(
'name' => 'Origin',
'value' => array($helper, 'formatOriginTerminal'),
),
array(
'name' => 'Destination',
'value' => array($helper, 'formatDestinationTerminal'),
),
array(
'name' => 'DepartureTime',
'header' => 'Departure',
'value' => array($helper, 'formatDepartureDate'),
),
array(
'name' => 'ArrivalTime',
'header' => 'Arrival',
'value' => array($helper, 'formatArrivalDate'),
),
array(
'name' => 'TripHrs',
'header' => 'Trip Hrs',
'value' => array($helper, 'formatTripDuration'),
),
'voyage.vessel.name::Vessel',
'service_class.name::Service Class',
'fare_set.fare_type::Fare Set',
array(
'class' => 'CButtonColumn',
'template'=>'{update}{delete1}',
'buttons'=>array(
'update' => array(
'label'=>'Edit',
'imageUrl'=>Yii::app()->baseUrl.'/images/gridview/update.png',
'url'=>'"#"',
'click'=>'function(){updateTripScheduleJs($(this).parent().parent().children(":nth-child(1)").text());}',
),
'delete1' => array(
'label'=>'Delete',
'imageUrl'=>Yii::app()->baseUrl.'/images/gridview/delete.png',
'url'=>'"#"',
'click'=>'function(){deleteTripScheduleJs($(this).parent().parent().children(":nth-child(1)").text());}',
),
),
),
),
));
?>
</div>
Views code of Add/Edit Dialog.
<?php
echo $form->dropDownList($model, 'service_class_id',
$serviceClassInfo->getAllServiceClassesForSelection2($model->ferry_operator_id,
$this->_ferryOperatorId , true, 'Select class'),
array(
'id' => 'service_class_id',
'class' => 'selectbox',
'ajax' => array(
'type'=>'POST',
'url'=>CController::createUrl('loadFareSet'),
'update'=>'#fare_set_id',
'data'=>array('service_class_id'=>'js:this.value'),
))
);
?>
In my Controller, below is my code.
<?php
class SiteController extends Controller
{
public $_ferryOperatorId;
public function actionRetrieveTripSchedule() {
$voyageServiceClassInfo = new VoyageServiceClassInfo;
if (isset($_POST['id']))
{
if (Yii::app()->request->isAjaxRequest)
{
$voyageServiceClassInfo = VoyageServiceClassInfo::model()->with('voyage')->findByPk($_POST['id']);
if ($voyageServiceClassInfo != null)
{
$this->_ferryOperatorId = '3';
$_json = array(
array('name'=>'voyage_service_class_id', 'value'=>$voyageServiceClassInfo->voyage_service_class_id),
array('name'=>'ferry_operator_id', 'value'=>$voyageServiceClassInfo->voyage->ferry_operator_id),
array('name'=>'origin_location_id', 'value'=>$voyageServiceClassInfo->voyage->origin_location_id),
array('name'=>'origin_pier_id', 'value'=>$voyageServiceClassInfo->voyage->origin_pier_id),
array('name'=>'destination_location_id', 'value'=>$voyageServiceClassInfo->voyage->destination_location_id),
array('name'=>'destination_pier_id', 'value'=>$voyageServiceClassInfo->voyage->destination_pier_id),
array('name'=>'departure_date', 'value'=>$voyageServiceClassInfo->voyage->departure_date),
array('name'=>'departure_time', 'value'=>$voyageServiceClassInfo->voyage->departure_time),
array('name'=>'arrival_date', 'value'=>$voyageServiceClassInfo->voyage->arrival_date),
array('name'=>'arrival_time', 'value'=>$voyageServiceClassInfo->voyage->arrival_time),
array('name'=>'vessel_id', 'value'=>$voyageServiceClassInfo->voyage->vessel_id),
array('name'=>'service_class_id', 'value'=>$voyageServiceClassInfo->service_class_id),
array('name'=>'fare_set_id', 'value'=>$voyageServiceClassInfo->fare_set_id),
);
echo CJSON::encode(array(
'status'=>'success',
'messages'=>"Target data is retrieved normally.",
'val'=>$_json,
));
}
else
{
echo CJSON::encode(array(
'status'=>'failure',
'messages'=>"Target data can not be retrieved from server.",
'val'=>$_json,
));
}
}
}
}
}
Models code of Service class drop down lists.
public function getAllServiceClassesForSelection2(
$operatorId = null, $operatorIdEdit = null, $addInstructionRow = false, $instruction = null)
{
$serviceClassArray = array();
if ($addInstructionRow) {
if ($instruction == null) {
$instruction = 'Select a ServiceClass';
}
$serviceClassArray += array('' => $instruction);
}
$criteria = new CDbCriteria;
$criteria->select = 'service_class_id, name';
if ($operatorId != null || $operatorId != '')
{
$criteria->condition = 'ferry_operator_id = ' . $operatorId;
}
if ($operatorIdEdit != null || $operatorIdEdit != '' && $model->operation_mode == AdminGeneralHelper::OPERATION_MODE_UPDATE)
{
$criteria->condition = 'ferry_operator_id = ' . $operatorIdEdit;
}
$criteria->order = 'name';
$servceClassInfos = $this->findAll($criteria);
foreach ($servceClassInfos as $servceClassInfo) {
$serviceClassArray += array(
$servceClassInfo->service_class_id => $servceClassInfo->name,
);
}
return $serviceClassArray;
}
In my JS file, below is my code.
function updateTripScheduleJs(id) {
// Get target data via controller and set values to fields of dialog.
$.blockUI({
message: "Loading data...",
});
$("#dialog-msg").html(""); // clear the message area of dialog
// Ajax request
$.ajax({
url: 'retrieveTripSchedule',
type: 'POST',
datatype: 'json',
data: $.parseJSON('{"id": '+id+'}'),
timeout: 20000,
beforeSend: function(){
},
success: function(data){
$.unblockUI();
var res = eval('(' + data + ')');
if (res.status == 'success'){
for (var idx in res.val){
if (res.val[idx].name == 'departure_time' || res.val[idx].name == 'arrival_time'){
$('#'+res.val[idx].name).attr('value',formatAMPM(res.val[idx].value));
} else {
$('#'+res.val[idx].name).attr('value',res.val[idx].value);
}
}
$("#operation_mode").attr('value','U'); // Set update mode
$(".submit-button").attr('value','Update Trip Schedule'); // Set submit button label
$(".update-only-div").css('display','block'); // Show columns for update
$(".create-only-div").css('display','none'); // Hide columns for update
$("#dialog").dialog("open");
} else {
alert("Trip Schedule does not exist. It may be deleted by other user");
$.fn.yiiGridView.update('tripschedules-grid'); // Refresh the list of service class.
}
},
error: function(){
$.unblockUI();
alert("Ajax Communication Error. Please contact system administrator.");
}
}
);
}
Below is the scenario:
I clicked the pencil icon, dialog will show. It will load all the
details depend on the selected row. This is correct.
It will load all the details. This is correct.
No. of values in Drop down lists for service class is wrong.
My expected output of service class is only 4 (based on DB) but in actual, all service class was displayed.
I found out that $this->_ferryOperatorId = '3' from controller that was used in views
($serviceClassInfo->getAllServiceClassesForSelection2($model->ferry_operator_id,
$this->_ferryOperatorId , true, 'Select class'))
has no value.
In my models code, if the ferryOperatorId = null, it will display all the
service class.
My question is what is the correct code for me to get the value of $this->_ferryOperatorId from controller
then used the value in views.
:(
Please help me to solve this.
I have a form (still not finished and is missing many fields) that is handled as a wizard with steps, in which fields from multiple entities are handled. This is the form itself:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('tipo_tramite', 'entity', array(
'class' => 'ComunBundle:TipoTramite',
'property' => 'nombre',
'required' => TRUE,
'label' => "Tipo de Trámite",
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('q')
->where('q.activo = :valorActivo')
->setParameter('valorActivo', TRUE);
}
))
->add('oficina_regional', 'entity', array(
'class' => 'ComunBundle:OficinaRegional',
'property' => 'nombre',
'required' => TRUE,
'label' => "Oficina Regional",
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('q')
->where('q.activo = :valorActivo')
->setParameter('valorActivo', TRUE);
}
))
->add('procedencia_producto', 'entity', array(
'class' => 'ComunBundle:ProcedenciaProducto',
'property' => 'nombre',
'required' => TRUE,
'label' => "Procedencia del Producto"
))
->add('finalidad_producto', 'entity', array(
'class' => 'ComunBundle:FinalidadProducto',
'property' => 'nombre',
'required' => TRUE,
'label' => "Finalidad del Producto"
))
->add('condicion_producto', 'entity', array(
'class' => 'ComunBundle:CondicionProducto',
'property' => 'nombre',
'required' => TRUE,
'label' => "Condición del Producto"
))
->add('lote', 'integer', array(
'required' => TRUE,
'label' => "Tamaño del Lote"
))
->add('observaciones', 'text', array(
'required' => FALSE,
'label' => "Observaciones"
));
}
I have a question regarding how to handle the parameter data_class in this case so I do not have to do magic in the controller. When I say magic I mean the following:
public function empresaAction()
{
$entity = new Empresa();
$form = $this->createForm(new EmpresaFormType(), $entity);
return array( 'entity' => $entity, 'form' => $form->createView() );
}
public function guardarEmpresaAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
/** #var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->container->get('fos_user.user_manager');
/** #var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */
$dispatcher = $this->container->get('event_dispatcher');
/** #var $mailer FOS\UserBundle\Mailer\MailerInterface */
$mailer = $this->container->get('fos_user.mailer');
$request_empresa = $request->get('empresa');
$request_sucursal = $request->get('sucursal');
$request_chkRif = $request->get('chkRif');
$request_estado = $request_empresa[ 'estado' ];
$request_municipio = $request->get('municipio');
$request_ciudad = $request->get('ciudad');
$request_parroquia = $request->get('parroquia');
$user = $userManager->createUser();
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);
if (null !== $event->getResponse())
{
return $event->getResponse();
}
$entity = new Empresa();
$form = $this->createForm(new EmpresaFormType(), $entity);
$form->handleRequest($request);
$success = $url = $errors = "";
if ($form->isValid())
{
if ($request_sucursal != NULL || $request_sucursal != "")
{
$padreEntity = $em->getRepository('UsuarioBundle:Empresa')->findOneBy(array( "padre" => $request_sucursal ));
if (!$padreEntity)
{
$padreEntity = $em->getRepository('UsuarioBundle:Empresa')->findOneBy(array( "id" => $request_sucursal ));
}
if ($request_chkRif != NULL || $request_chkRif != "")
{
$rifUsuario = $request_empresa[ 'tipo_identificacion' ] . $request_empresa[ 'rif' ];
}
else
{
$originalRif = $padreEntity->getRif();
$sliceRif = substr($originalRif, 10, 1);
$rifUsuario = $originalRif . ($sliceRif === false ? 1 : $sliceRif + 1);
}
$entity->setPadre($padreEntity);
}
else
{
$rifUsuario = $request_empresa[ 'tipo_identificacion' ] . $request_empresa[ 'rif' ];
}
$user->setUsername($rifUsuario);
$user->setRepresentativeName($request_empresa[ 'razon_social' ]);
$user->setEmail($request_empresa[ 'usuario' ][ 'email' ]);
$user->setPlainPassword($request_empresa[ 'usuario' ][ 'plainPassword' ][ 'first' ]);
$pais = $em->getRepository('ComunBundle:Pais')->findOneBy(array( "id" => 23 ));
$user->setPais($pais);
$estado_id = $request_estado ? $request_estado : 0;
$estado = $em->getRepository('ComunBundle:Estado')->findOneBy(array( "id" => $estado_id ));
$user->setEstado($estado);
$municipio_id = $request_municipio ? $request_municipio : 0;
$municipio = $em->getRepository('ComunBundle:Municipio')->findOneBy(array( "id" => $municipio_id ));
$user->setMunicipio($municipio);
$ciudad_id = $request_ciudad ? $request_ciudad : 0;
$ciudad = $em->getRepository('ComunBundle:Ciudad')->findOneBy(array( "id" => $ciudad_id ));
$user->setCiudad($ciudad);
$parroquia_id = $request_parroquia ? $request_parroquia : 0;
$parroquia = $em->getRepository('ComunBundle:Parroquia')->findOneBy(array( "id" => $parroquia_id ));
$user->setParroquia($parroquia);
...
}
else
{
$errors = $this->getFormErrors($form);
$success = FALSE;
}
return new JsonResponse(array( 'success' => $success, 'errors' => $errors, 'redirect_to' => $url ));
}
Since the 'data_classonEmpresaFormTypeis set toUsuarioBundle\Entity\Empresa` then I need to handle any extra parameter as example above show with getter/setter and that's a lot of work for complex/big forms.
In the sample form, the fields tipo_tramite will persist in the class ComunBundle\Entity\Producto but the field oficina_regional will persist in the class ComunBundle\Entity\SolicitudUsuario and so with others who are not placed even here but they are in the form, in total should persist as 3 or 4 entities including relationships in many cases, how do you handle this?
I know there is CraueFormFlowBundle that maybe cover this process/flow but not sure if it is the solution to go.
Any advice?
Just worked with multi-step form few days ago. I think you need embedded forms here. Anyway can suggest you another nice bundle for creating wizard: SyliusFlowBundle. IMO it's more flexible and easier to understand than CraueFormFlowBundle.
BTW why do you want to store all in one form? We've used one form for each step, and I liked this approach.
Actually I'm developing a simple file uploader.
In the ImageUploader.php file I define the getInputFilter function, all works unless I try to add a File\MimeType validator:
<?php
namespace Admin\Model;
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
use Zend\Validator\File\MimeType; //tried also with use Zend\Validator\File;
[...]
public function getInputFilter()
{
[...]
$inputFilter->add($factory->createInput(array(
'name' => 'image',
'required' => true,
'validators' => array(
array(
'name' => 'MimeType', //tried also with File\MimeType
'options' => array(
'mimeType' => array('image/jpeg'),
),
),
),
)));
[...]
}
What's the correct way to define a File\Validator\MimeType?
Thank you in advance.
Here is a sample from my project with a couple of other useful features (renaming for example):
use Zend\File\Transfer\Adapter\Http,
Zend\Validator\File\Size,
Zend\Validator\File\IsImage;
[...]
public function editAction() {
[...]
if ($request->isPost()) {
$params = $this->params()->fromPost();
$files = $this->params()->fromFiles();
$images = array();
if(!empty($files['main_image']['name'])) $images['main_image'] = $files['main_image']['name'];
if(!empty($files['detailed_image']['name'])) $images['detailed_image'] = $files['detailed_image']['name'];
if(!empty($images)) {
$adapter = new Http();
$size = new Size(array('max'=>1000000));
$is_image = new IsImage();
$image_errors = array();
foreach ($images as $field => $filename) {
$adapter->setValidators(array($size,$is_image), $filename);
if (!$adapter->isValid($filename)) {
$adapter_errors = $adapter->getMessages();
$errors = array();
foreach($adapter_errors as $key=>$row) {
$errors[] = $row;
}
if(!empty($errors)) {
array_push($image_errors, $errors);
$form->setMessages(array($field => $errors));
}
} else {
$adapter->setDestination(IMAGES_PATH);
$fileinfo = $adapter->getFileInfo();
preg_match('/.+\/(.+)/', $fileinfo[$field]['type'], $matches);
$extension = $matches[1];
$old_filename = $item->__get($field);
$new_filename = $item->id.'_'.$field.'.'.$extension;
$adapter->addFilter('File\Rename',
array(
'target' => IMAGES_PATH.$new_filename,
'overwrite' => true,
)
);
if($adapter->receive($fileinfo[$field]['name'])) {
if(!empty($old_filename) && $old_filename != $new_filename &&
file_exists(IMAGES_PATH.$old_filename)) {
unlink(IMAGES_PATH.$old_filename);
}
$params[$field] = $new_filename;
}
}
}
}
}
[...]
}
[...]
The code however could be refactored to move the logic to some lib or model.
Not sure which version you are using now but with Zendframework 2.4 you can now do this. Hope this helps.
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$inputFilter->add(array(
'name' => 'fileupload',
'required' => true,
'allow_empty' => false,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'Zend\Validator\File\UploadFile',
'name' => 'Zend\Validator\File\MimeType',
'options' => array(
'mimeType' => 'audio, video, image',
),
),
),
));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
This function sets up the Magento Grid to display a list of filenames with a corresponding 'Delete' action.
The problem is the Delete action never passes the parameter, 'filename.' (See http://www.premasolutions.com/content/magento-manage-category-product-grid-edit-link) I have TESTDUMP for verification but it never prints on the next page.
Is 'params' a legitimate action of 'addColumn->actions->url'?
Update: Added the construct and prepare collection for controller. Maybe it's because of the type of Collection I'm using?
class Rogue_Googlemerchant_Block_Adminhtml_Exporter_Grid
Rogue_Googlemerchant_Block_Adminhtml_Exporter_Grid extends Mage_Adminhtml_Block_Widget_Grid
{
public function __construct()
{
parent::__construct();
$this->setId('googlemerchantGrid');
// This is the primary key of the database
$this->setDefaultSort('filename');
$this->setDefaultDir('ASC');
$this->setSaveParametersInSession(true);
}
protected function _prepareCollection()
{
$basePath = Mage::getBaseDir('base');
$feedPath = $basePath . '/opt/googlemerchant/';
$errPath = $basePath . '/var/log/googlemerchant/';
$flocal = new Varien_Io_File();
$flocal->open(array('path' => $feedPath));
$dataCollection = new Varien_Data_Collection();
foreach ($flocal->ls() as $item) {
$dataObject = new Varien_Object();
$dataObject->addData(
array(
'filename' => $item['text'],
'size' => $item['size'] / 1000 . ' kb',
'date_modified'=> $item['mod_date']
)
);
$dataCollection->addItem($dataObject);
}
$this->setCollection($dataCollection);
return parent::_prepareCollection();
}
protected function _prepareColumns()
{
$this->addColumn('filename', array(
'header' => Mage::helper('googlemerchant')->__('File'),
'align' =>'left',
'index' => 'filename',
'width' => '200px',
));
$this->addColumn('action', array(
'header' => Mage::helper('googlemerchant')->__('Action'),
'width' => '50px',
'type' => 'action',
// 'getter' => 'getId',
'actions' => array(
array(
'caption' => Mage::helper('googlemerchant')->__('Delete'),
'url' =>
array(
'base' => '*/*/delete',
'params' => array('filename' => 'TESTDUMP')
),
'field' => 'filename'
)
),
'filter' => false,
'sortable' => false,
// 'index' => 'filename',
// 'is_system' => true,
));
}
}
class Rogue_Googlemerchant_Adminhtml_ExporterController
class Rogue_Googlemerchant_Adminhtml_ExporterController extends Mage_Adminhtml_Controller_Action
{
public function deleteAction()
{
$filename = $this->getRequest()->getParam('filename');
$basePath = Mage::getBaseDir('base');
$feedPath = $basePath . '/opt/googlemerchant/';
$errPath = $basePath . '/var/log/googlemerchant/';
$flocal = new Varien_Io_File();
$flocal->open(array('path' => $feedPath));
d($filename);
if ($filename) {
try{
$flocal->rm($filename);
Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('googlemerchant')->__('The file has been deleted.'));
$this->_redirect('*/*/');
}
catch (Mage_Core_Exception $e) {
$this->log($e);
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
$this->_redirect('*/*/index');
return;
}
}
die('here');
Mage::getSingleton('adminhtml/session')->addError(Mage::helper('adminhtml')->__('Unable to find the file to delete.'));
$this->_redirect('*/*/');
}
}
The getter of the action column is used on the collection items to retrieve the argument value for the field parameter.
I'm not sure why you are specifying the filename hardcoded or if that should work, but if you add the column configuration
'getter' => 'getFilename'
and remove the params from the action it should work.