I am developing a Yii 2.0 application in which users can create orders then send the orders to review and after that it follows a number of stages in the workflow.
Everything is ok until yesterday that the customer ask for the possibility that before sending the orders to review the order are considered as draft. Which means I have to turn off validations on create and validate them when users clicks Send To Review button. I know Yii 2.0 supports scenarios but maybe scenarios doesn't apply to this because the Send To Review button is shown in a readonly view. This forces me to do validation inside the controller action because there is no send_to_review view. How can this be done (I mean model validation inside controller action)?
Here is the controller action code
public function actionSendToReview($id)
{
if (Yii::$app->user->can('Salesperson'))
{
$model = $this->findModel($id);
if ($model->orden_stage_id == 1 && $model->sales_person_id == Yii::$app->user->identity->id)
{
$model->orden_stage_id = 2;
$model->date_modified = date('Y-m-d h:m:s');
$model->modified_by = Yii::$app->user->identity->username;
//TODO: Validation logic if is not valid show validation errors
//for example "For sending to review this values are required:
//list of attributes in bullets"
//A preferred way would be to auto redirect to update action but
//showing the validation error and setting scenario to
//"send_to_review".
$model->save();
$this::insertStageHistory($model->order_id, 2);
return $this->redirect(['index']);
}
else
{
throw new ForbiddenHttpException();
}
}
else
{
throw new ForbiddenHttpException();
}
}
What I need to solve is the TODO.
Option 1: Showing validation errors in the same view and the user has to clic Update button change the requested values save and then try to Send To Review again.
Option 2: Redirecting automatically to update view already setting scenario and validation errors found in the controller.
Thanks,
Best Regards
You can use $model ->validate()for validation in controller.
public function actionSendToReview($id)
{
if (Yii::$app->user->can('Salesperson'))
{
$model = $this->findModel($id);
if ($model->orden_stage_id == 1 && $model->sales_person_id == Yii::$app->user->identity->id)
{
$model->orden_stage_id = 2;
$model->date_modified = date('Y-m-d h:m:s');
$model->modified_by = Yii::$app->user->identity->username;
//TODO: Validation logic if is not valid show validation errors
//for example "For sending to review this values are required:
//list of attributes in bullets"
//A preferred way would be to auto redirect to update action but
//showing the validation error and setting scenario to
//"send_to_review".
//optional
$model->scenario=//put here the scenario for validation;
//if everything is validated as per scenario
if($model ->validate())
{
$model->save();
$this::insertStageHistory($model->order_id, 2);
return $this->redirect(['index']);
}
else
{
return $this->render('update', [
'model' => $model,
]);
}
}
else
{
throw new ForbiddenHttpException();
}
}
else
{
throw new ForbiddenHttpException();
}
}
If you don't need validation in actionCreate().Create a scenario for not validating any field and apply there.
Related
i have a logic whereby on form submission i want to return to specific page based on a certain value the user choosed when submiting the form.the form works well but when i try to return it doesnt work.where might i be missing the point here.
public function addtoorder(Request $request){
$userid=Auth::user()->id;
$addresses=Deliveryaddress::where('user_id',$userid)->first();
if($request->isMethod('post')){
$data=$request->all();
$order = new Order();
$order->name = Auth::user()->name;
$order->phone =$addresses->phone;
$order->county =$addresses->shipcharges->county;
$order->town =$addresses->towns->town;
$order->order_status="New Order";
$order->payment_method = $request->payment_method;
$order->user_id =$userid;
$order->grand_total = Session::get('grand_total');
$order->shipping_charges=$addresses->shipping_cost;
$order->save();
}
if($data=="SKRILL"){
return view('frontend.product.skrill');
}elseif($data=="PAYPAL"){
return view('frontend.product.paypal');
}
}
}
i have been able to save the data on the database but am unable to return to the specific pages.rather it return to blank page without any error,but it saves the data to the orders table perfectly.
I guess blank screen means that nothing was returned, because you are trying to check whether $data(which is array) is equal to some string.
My thoughts would be for you to try check string in your if statement.
Like this
if($data['payment_method'] === "SKRILL"){
return view('frontend.product.skrill');
}elseif(data['payment_method'] === "PAYPAL"){
return view('frontend.product.paypal');
}
I've created a plugin to extend the User plugin and I now want to extend the update function of its controller.
Actually what I'd like to do is to check some data when an admin
clicks on the Update button then, according to the data, let the admin edit the user form as usual or redirect him to the user list.
I'm trying to do this through a route in my plugin:
Route::get('backend/rainlab/user/users/update/{id}', '\RainLab\User\Controllers\Users#check_update');
in my Plugin.php file
public function boot()
{
\RainLab\User\Controllers\Users::extend( function($controller) {
$controller->addDynamicMethod('check_update', function($recordId = null, $context = null) use ($controller) {
return $controller->asExtension('FormController')->update($recordId, $context);
});
});
}
But I get a blank page. The user form is not displayed.
Can someone helps me ?
This wont work as it will break life-cycle of back-end and direct call method of controller.
As other solution, we can use events :) - backend.page.beforeDisplay
In your plugin's plugin.php file's boot method
public function boot() {
\Event::listen('backend.page.beforeDisplay', function($controller, $action, $params) {
if($controller instanceof \RainLab\User\Controllers\Users) {
// for update action
if($action === 'update') {
// check data ($params) and make decision based on that
// allow user to edit or NOT
if(true) {
// just redirect him to somewhere else
\Flash::error('Please No.');
return \Redirect::to('/backend/rainlab/user/users');
}
// if all good don't return anything and it will work as normal
}
}
});
}
it will do the job based on condition you can allow user to edit OR not (redirect him with message to other action).
if any doubts please comment.
i have a controller with 5 methods store / rename / duplicate / move / delete
comming from deferent Forms with POST.
And i want to use Form Request for Validation like that :
any adea on how to validate all my forms without creating a request form file for each Form.
You can use $this->route()->getActionName() to the get the current action. ie. MyController#store, MyController#rename, MyController#delete, ...
Then in your SectionRequest you can do something like this:
public function rules(){
$arr = explode('#', $this->route()->getActionName());
$method = $arr[1]; // The controller method
switch ($method) {
case 'store':
// do something.
break;
case 'rename':
// do something.
break;
case 'delete':
// .... and so
}
}
I have an observer action setup, that checks if a product page is loaded. If so, it calls a custom help that deals with all of the GET paremeters. It used to work for over 4 years and have suddenly stopped (the only thing that changed on the 3rd party's side is the naming of those parameters).
Here is the observer action:
public function productView($observer) {
/*#var $block Mage_Core_Block_Abstract*/
$block = $observer->getEvent()->getBlock();
if ($block && $this->getProduct()){
if ($block->getModuleName() == 'Mage_Catalog'){
$productId = $this->getProduct()->getEntityId();
//If params exist - save
if ($this->ParamsHelper()->saveParams($productId)){
//code omitted
}
}
}
}
Here is the helper's action:
public function saveParams($productId) {
if (is_numeric($productId)){
$params = Mage::app()->getRequest()->getParams();
if (!empty($params['image']) && !empty($params['config'])){
//never gets here
return true;
}
}
return false;
}
If I try to var_dump the $params, I get the following array which only includes product_id:
array(1) { ["id"]=> string(3) "664" }
Expected result is to be able to access all the GET parameters passed via url in product view.
Any help or guidance is much appreciated.
EDIT
Product URLs are similar to product names, like f.e.:
domain.com/red-jacket
In a perfect case, I would expect to get parameters passed like following:
domain.com/red-jacket?param1=aaa¶m2=bbb
Not sure whats the exact problem is ... but for domain.com/red-jacket?param1=aaa¶m2=bbb you can get parameters in this way:
$params = Mage::app()->getRequest()->getParams();
$param1 = $params['param1']
or
$param1 = Mage::app()->getRequest()->getParam('param1');
//code for get parameters in view page.
$arrParams = Mage::app()->getRequest()->getParams();
echo "Get Parameter"; echo '<pre>', print_r($arrParams);
I'm using Cakephp and trying to put in a method to make sure our reservation system doesn't let two users book the same appointment. Ex. User 1 opens the appointment, and User 2 opens it simultaneously. User 1 books the appointment. User 2 tries to book it but the system checks and sees it is no longer available.
I imagine this would take place in validation, or in a beforeSave(), but can't figure out how to do it.
Right now I made a function in the model to call from the controller. In the controller I have:
if ($this->Timeslot->checkIfNotAvailable()) {
$this->Session->setFlash('This timeslot is no longer available');
$this->redirect(array('controller' => 'users', 'action' => 'partner_homepage'));
}
and in the model I have this function:
function checkIfNotAvailable($data) {
$this->recursive = -1;
$timeslot = $this->find('all', array(
'conditions' => array(
'Timeslot.id' => $this->data['Timeslot']['id'])
)
);
if ($timeslot['student_id'] == 0) {
//They can reserve it, do not spring a flag
return false;
} else {
//Throw a flag!
return true;
}
}
I think I'm mixed up using custom validation when it's not called for. And it's not working obviously. Any suggestions?
Thanks!
If what you have is working, you can stick with it, you could also try creating a beforeValidate() call back function in your Model.
class YourModel extends AppModel {
function beforeValidate(){
if( !$this->checkIfNotAvailable( $this->data ) ) {
unset($this->data['YourModel']['time_slot']);
}
return true; //this is required, otherwise validation will always fail
}
}
This way you remove the time_slot before it goes to validation and it will drop a validation error at that point, kicking the user back to the edit page and getting them to pick a different time slot, ideally the updated data entry page will no longer have the used time slot available.