If I grab a value from my form in my controller using:
$jinput = JFactory::getApplication()->input;
$add_name = $jinput->get('name', 'Default name', 'STRING');
I expect the default value to be set as a string called Default name.
But if I test this it doesn't seem to think there is a value:
if (!empty($add_name))
{
//do stuff
//I expect to be here because $add_name="Default name"
}
else
{
//I actually go here
}
Am I misunderstanding the default value?
EDIT
If a form is submitted with an empty string then that is what will be returned. I understand that (now). But under what circumstance will the default value Default name ever get assigned to $add_name
If you submitted an empty string in your form, then it's used instead of the default value. JInput does isset() check, not empty(), so empty string is considered as a valid value.
Related
I'm not sure how they work, I was thinking that accessor fires when you access the attribute, however when I try to insert new record my accessor fires. I store in my database only image_name by removing URL and I use an accessor to include my URL route when I retrieve my image name. I found out that my accessor fires on insert and change my input:
ImageRepository.php
public function save($imageData)
{
$this->model->owner()->associate(auth()->user());
$this->model->type = $imageData->type;
$this->model->image_name = $imageData->image_url;
$this->model->save();
return $this->model;
}
Image.php
public function getImageNameAttribute($value)
{
$filePath = 'my_path';
// check if method was hit
logger()->info('getImageNameAttribute: '.$value);
// return default image if not found
if ($value == '' || $value == null || Str::contains($value, 'no-image.png') || !File::exists(public_path($filePath))) {
return asset('img/no-image.png');
} else {
return asset($filePath);
}
}
Input for $imageData->image_url:
https://some-random-image-url/image-name.jpg
Inserted data:
img/no-image.png
Excepted output (I have a function that extracts the name from URL):
image-name.jpg
When I check the log, I get the message:
getImageNameAttribute: https://some-random-image-url/image-name.jpg
Can someone explain to me if I'm doing something wrong or this is working as pretended?
I did solve the problem, I miss checked. Actually inserted record in my database is correct:
image-name.jpg
But I was checking dd() output after the insert and the value from there was not correct:
img/no-image.png
Because when dd() fires, the accessor is also fired (as we are retrieving data) and as the image was not downloaded it was actually showing correct data.
On a Yii2 project, in a user's Edit Info form (inside a modal):
I'm currently figuring out which fields were changed using the jQuery .change() method, and I'm grabbing their value with jQuery's .val() method.
However, I want to do less with JavaScript and do more with Yii's framework.
I can see in the Yii debugger (after clicking into the AJAX POST request) that Yii is smart enough to know which fields were changed -- it's showing SQL queries that only UPDATE the fields that were changed.
What do I need to change in the controller of this action to have Yii include the name of the field changed -- including it's value -- in the AJAX response? (since my goal is to update the main view with the new values)
public function actionUpdateStudentInfo($id)
{
$model = \app\models\StudentSupportStudentInfo::findOne($id);
if ($model === null) {
throw new NotFoundHttpException('The requested page does not exist.');
}
$model->scenario = true ? "update-email" : "update-studentid";
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->renderAjax('_student_support_alert_success');
}
return $this->renderAjax("_edit_student_info",[
"model" => $model,
]);
}
I'm currently returning a static success view.
You can use $model->dirtyAttributes just after load the data to get a $attrib => $value pair array.
http://www.yiiframework.com/doc-2.0/yii-db-baseactiverecord.html#getDirtyAttributes()-detail (this docs says:)
Returns the attribute values that have been modified since they are loaded or saved most recently.
The comparison of new and old values is made for identical values using ===.
public array getDirtyAttributes ( $names = null )
(sorry for formatting, sent by mobile)
I have a form. When validation fails i redirect to the same page. "mobilepage1.blade.php"
But all my entries are all gone. I want all my entries to stay. Exept the password.
I redirect my page with View::make
return View::make('mobilepages.mobilepage1', array('errormessages' => 'errormessages'));
I use:
$input = Input::all();
to get the input.
All input
return Redirect::to('mobilepages')->withInput(Input::all());
Except password
return Redirect::to('mobilepages')->withInput(Input::except('password'));
Old Input
In your form view, use something like this for the inputs:
<?= Form::text('title', (Input::get('title') ?: NULL)); ?>
The (Input::get('title') ?: NULL) operator will return the previous title value if it was set and nothing if it wasn't set.
It should be done using something like this:
public formSubmitMethod() // Change formSubmitMethod with appropriate one
{
// This is the form submit handler
// Set rules and validate the inputs
$rules = array(...); // set rules here but there are other ways
$inputs = Input::except('_token'); // everything but _token
$validatior = Validator::make($input, $rules);
if($validatior->fails()) {
// Validation failed
return Redirect::back()->withInput()->withErrors($validatior);
}
else {
// Success
// Do whatever you want to do
}
}
In your form, use Input::old('fieldname'), something like this:
{{ Form::input('username', Input::old('fieldname')) }}
That's it, now if you redirect back for invalid user inputs then your form fields will be repopulated with old values. Don't use old() method in the password field. You can also access the error message for a field using something like {{ $errors->first('username') }}, so if this (username) field invalidated then the error message for this field will be printed out.
Also, notice that, to redirect back, I've use Redirect::back() not View::make(), it's (make) not for redirecting but for rendering a view to show it.
Im building my own web service on the premise of 2-legged OAuth.
With each authenticated request there will be an included HMAC.
I know it could be done like this:
public ActionResult userInfoExample(string HMAC, string username)
{
MyMembership.checkHMAC(HMAC);
//get user
return View();
}
but that is fairly nasty, because HMAC needs to be included in the parameters for every action. Its weakly typed and crap.
I wanted to do something like this:
[AuthorizeHMAC]
public ActionResult userInfoExample(string username)
{
//get user
return View();
}
I found this, and it mentioned I should look at Custom Modal Binders, so then I found this and after reading it I am unsure how I could make that work.
My goal is to authenticate (/authorise) using a HMAC that (I assume) is placed in the URL parameters i.e.: http:// www.website.com/foo/bar?username=xxx&hmac=xxxxxxxxx
I would like to know if anyone has any references I can read or a direct solution.
I am also welcome to criticism on my fundamental understanding of API security, or how I am doing things, I am fairly new to this area of
Check out my code at
http://mvcsecurity.codeplex.com/
I do something similar to validate parameters on the page (it is not an HMAC though). Since you will be generating it on the View Im assuming (or passing it to the view) you can check it the same way a similar way I check it in my attribute.
From:
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//The hidden form field that contains our hash - for ex. CustomerId is rendered as a hidden input id="_CustomerIdToken"
string encryptedPropertyName = string.Format("_{0}Token", _propertyName);
//grab the token
string hashToken = filterContext.HttpContext.Request.Form[encryptedPropertyName];
//The encrypted form data MUST be there. We do not allow empty strings otherwise this could give
//an attack vector in our filter as a means to bypass checks by simply passing in an empty validation token.
if (string.IsNullOrEmpty(hashToken))
{
throw new MissingFieldException(string.Format("The hidden form field named value {0} was missing. This is created by the Html.AntiModelInjection methods. Ensure the name used on your [ValidateAntiModelInjectionAttribute(\"!HERE!\")] matches the field name used in Html.AntiModelInjection method. If this attribute is used on a controller method that is meant for HttpGet, then the form value would not yet exist. This attribute is meant to be used on controller methods accessed via HttpPost.", encryptedPropertyName));
}
//Get the plain text value
string formValue = filterContext.HttpContext.Request.Form[_propertyName];
//Plain text must be available to compare.
if (string.IsNullOrEmpty(formValue))
{
throw new MissingFieldException(string.Format("The form value {0} was missing. If this attribute is used on a controller method that is meant for HttpGet, then the form value would not yet exist. This attribute is meant to be used on controller methods accessed via HttpPost.", _propertyName));
}
//We cannot encrypt the form value and compare to the previously encrypted form token.
//Each time you Encrypt() with the MachineKey class even using the same plain text, the end result is difference.
byte[] plainTextBytes = MachineKey.Decode(hashToken, MachineKeyProtection.Encryption);
string plainText = Encoding.Unicode.GetString(plainTextBytes);
//And compare
if (string.Compare(plainText, formValue , false, CultureInfo.InvariantCulture) != 0)
{
throw new HttpAntiModelInjectionException(string.Format("Failed security validation for {0}. It is possible the data was tampered with as the original value used to create the form field does not match the current property value for this field. Ensure if this is a web farm, the machine keys are the same.",_propertyName));
}
filterContext.HttpContext.Trace.Write("(Logging Filter)Action Executing: " +
filterContext.ActionDescriptor.ActionName);
base.OnActionExecuting(filterContext);
}
I have added an extra field in the admin_role table in magento called limit_products. I have also added an extra field into the magento backend, and using the admin_permissions_role_prepare_save event I set this field to either 1 or 0, using the function below. However, it doesn't seem to want to save this field at all. Any ideas what I am doing wrong? I even tried setting the field in RoleController.php (where the other fields are set), but no luck. Anyone know what I'm doing wrong?
public function adminPermissionsRolePrepareSave(Varien_Event_Observer $observer) {
$role = $observer->getEvent()->getObject();
$request = $observer->getEvent()->getRequest();
//fb($request);
$role->setLimitProducts((bool)$request->getPost('limit_products', false));
return $this;
}
EDIT: I just realised I forgot to mention that $request->getPost('limit_products', false); does return the right value, it's just the $role->setLimitProducts(); isn't saving it. Also when I do $role->getLimitProducts(); it does return the right value.