Pass error message from controller to view in zf2 - zend-framework2

I have simple login in zf2. I want to show error message error to user when username/password didn't match.
In view/login.php:
if (isset($error_msg))
{
echo $error_msg;
}
In Controller I have:
$msg = array('error_msg' => 'Invalid Username or Password');
return $this->redirect()->toRoute('login', $msg);
Here error_msg cannot passed to view, what are wrong with this?
Furthermore I also try
$model = new ViewModel(array(
'error_msg' => 'Wrong username or password',
));
$model->setTemplate('login/index');
return $model;
But here link didn't go to login/index. but instead go to login/process. Process is the action in which login is processed.
Help me friends please. I want to pass error message from controller to view . So how should I do it.

Just put your login process code into your login index action, there's no need to have two actions for this. When you have processed your login and determined that it has failed simply pass your error message to your view model and display it in your view. This can be done in several ways.
$viewModel = new ViewModel();
$viewModel->error_msg = 'Wrong username or password';
return $viewModel;
return new ViewModel(array(
'error_msg' => 'Wrong username or password',
));
or simply
return array(
'error_msg' => 'Wrong username or password',
);

Related

Server side Rails model validation in a React form

I am trying to validate User inputs on server side in a Rails Application with React as view. Basically I make axios calls to the Rails API like this:
const Script = props => {
const [script, setScript] = useState({})
const [scene, setScene] = useState({})
const [loaded, setLoaded] = useState(false)
useEffect(() => {
const scriptID = props.match.params.id
const url = `/api/v1/scripts/${scriptID}`
axios.get(url)
.then( resp => {
setScript(resp.data)
setLoaded(true)
})
.catch(resp => console.log(resp))
}, [])
const handleChange = (e) => {
e.preventDefault()
setScene(Object.assign({}, scene, {[e.target.name]: e.target.value}))
}
const handleSubmit = (e) => {
e.preventDefault()
const csrfToken = document.querySelector('[name=csrf-token]').content
axios.defaults.headers.common['X-CSRF-TOKEN'] = csrfToken
const script_id = script.data.id
axios.post('/api/v1/scenes', {scene, script_id})
.then(resp => {
const included = [...script.included, resp.data.data]
setScript({...script, included})
})
.catch(err => {
console.log(err.response.data.error)
})
.finally(() => {
setScene({name: '', description: ''})
})
}
All data gets passed into a react component with a form.
return (
<div className="wrapper">
{
loaded &&
<Fragment>
.
.
.
<SceneForm
handleChange={handleChange}
handleSubmit={handleSubmit}
attributes={script.data.attributes}
scene={scene}
/>
</Fragment>
}
</div>
)
In this form I have a name field and the corresponding name in Rails has a validation uniqueness: true. everything works fine if I enter a valid (unique) name.
I tried to implement a validation but I am not happy with the outcome. (It works in general: my no_errors? method does what is is supposed to do and I get a 403 status) This is the controller part:
def create
scene = script.scenes.new(scene_params)
if no_error?(scene)
if scene.save
render json: SceneSerializer.new(scene).serialized_json
else
render json: { error: scene.errors.messages }, status: 422
# render json: { error: scene.errors.messages[:name] }, status: 423
end
else
render json: { error: "name must be unique" }, status: 403
end
end
.
.
.
private
def no_error?(scene)
Scene.where(name: scene.name, script_id: scene.script_id).empty?
end
If I enter an existing name I get a console.log like this:
screenshot
Here is my concern: I am not happy with my approach of error handling in general. I do not want to get the 403 message logged to the console (I do want to avoid this message in the first place).
My idea is to take the "simple form" approach: Make the border of my field red and post an error message under the field, without any console output...
And on a side note: Is 403 the correct status? I was thinking about 422 but wasn't sure...
Thank you for your ideas in advance!
403 is the wrong status code. What you need is to return a 422 (unprocessable entity). 403 is more about policy and what you are authorized to do.
Then when you deal with http request it's a standard to have a request and status code printed in browser console. Not sur to get your issue here.
If it's about to display the error you could just have a function that colorize (or whatever fireworks you want) your input if the status code response is a 422.

how to check available in client side with ajax, ruby on rails

I'm new in ruby on rails, and i'm trying to check validate with ajax in client side(NOT CHECK AFTER POST), I have succeeded in checking not null, but i don't know to check available. I tried some codes but i have this error:
NameError in Welcome#index
../welcome/index.html.erb where line #17 raised:
undefined local variable or method `name' for #<#<Class:0x3d80e28>:0x3354b58>
Extracted source (around line #17):
14: } else if (phonenumber == "" && email == ""){
15: alert("Please enter your email or phonenumber in the form");
16: return false;
17: } else if (<% #usernames.include?("#{name}")%>){
18: alert("Please change your name");
19: }
20: });
Here is my ajax in html:
<script>
$(document).ready(function() {
$("#button").click(function() {
var email = $("#email").val();
var name = $("#username").val();
var phonenumber = $("#phonenumber").val();
var pass = $("#password").val();
if (name == "") {
alert("Please enter your Name in the form");
return false;
} else if (pass == "") {
alert("Please enter your Password in the form");
return false;
} else if (phonenumber == "" && email == ""){
alert("Please enter your email or phonenumber in the form");
return false;
} else if (<% #usernames.include?("#{name}")%>){
alert("Please change your name");
}
});
});
</script>
Because i want to check username in client side, so i must call '#usernames' in controller, here is my controller:
def index
#usernames = User.find(:all, :select => "username")
#user = User.create(:username => params[:username], :password => params[:password],
:email => params[:email], :phonenumber => params[:phonenumber])
if #user
render 'index'
else
render 'index'
end
end
I know my problem is I don't have 'name' method in controller, but i want to check "name" in client side. So please help me to fix that! Or help me to try another way to check available :)
Update:
I tried to create :
var names = <%= #usernames%>
but i have this error in log:
SyntaxError: illegal character
Are you trying to populate all the usernames in js? Really ? Don't do it, you're in a way exposing all the usernames to people while you are trying to validate it instantly.
For client side validation you could use jquery validation plugin which could be found here which separates validation from rest of your js code.
Also to validate if a username is available to be allotted to a user, you can fire ajax when user starts typing. Additionally you can rely on model errors for uniqueness.
In your model you could write validates :username, :uniqueness => true so you don't have to change your code and rails will give you appropriate error messages.
I hope that helps.

How to pass value through link in controller function

How to pass value through link in controller function.
I want to pass below rc value in link so that routes collect it and send to controller.I am new bies in rails.Anyone please help me to solve the problem.
my html.erb .which collect value from text box through jQuery function.
<script type="text/javascript">
var rc=jQuery("#commonid").val();
</script>
<div ><%=link_to "Alert By Region",alerts/filter_alert %></div>
my routes.rb
file which match the link and send to controller
match 'alerts/filter_alert', :controller => 'alerts', :action => 'filter_alert'
my controller
def filter_alert(x)
#message=x
#title = #title + ' - Alerts'
render :site_alerts
end
Javascript things belong to Javascript. You need to manipulate this value dynamically upon visitor's clicking this link.
In Rails' controller side, you can't hard code the method. You need to use params from query string because you won't know what the input is.
# Views
link_to 'Alert By Region', 'alerts/filter_alert', id: 'alert-link'
# Javascript
$('#alert-link').on('click', function() {
var rc = $("#commonid").val();
if rc {
this.attr['href'] += '?rc='+ encodeURI(rc);
return true;
} else {
alert 'input is blank!';
return false;
}
});
# Controller
def filter_alert
rc = params[:rc]
# Then process based on this
end

Get Most Recent Employer using Facebook Graph API

How can I get the most recent employer for a logged in user using the Graph API? I know I can find all listed employers using:
https://graph.facebook.com/me/friendlists/work
And I can use the returned number from the 'id' field and tack on '/members' to get the members of that group.
Any help would be greatly appreciated.
<?php
$config = array(
'appId' => FB_APP_ID,
'secret' => FB_SECRET_KEY,
'cookie' => true // enable optional cookie support
);
$facebook = new Facebook($config);
$user = $facebook->getUser();
$params = array(
'scope' => 'user_work_history',
'redirect_uri' => FB_APP_URL,
);
$loginUrl = $facebook->getLoginUrl($params);
if ($user) {
try {
$user_profile = $facebook->api('/me');
var_dump($user_profile["work"][0]["employer"]["name"]); //will display most recent eployer
} catch (FacebookApiException $e) {
$user = null;
}
}
else
{
?>
<script>top.location.href = "<?php echo $loginUrl?>";
<?php
}
?>
This functionality appears to be provided at user endpoint using additional parameters concordant with your search.
For example:
https://graph.facebook.com/me?fields=work
From the documentation:
work: A list of the user's work history
Permission tokens: user_work_history or friends_work_history
Returns: array of objects containing employer, location, position, start_date and end_date fields
You can reasonably find the user's current employer by inspecting the start_date and end_date respectively. For a different user than the current user, replace me with the desired PROFILE_ID.

cakePHP passing URLs as a param

I have an ImportController with a function admin_getcontents.
function admin_getcontents($url = null)
{
$contents = json_decode(file_get_contents(($url)),true);
//some stuff
}
Through ajax I call /admin/import/getcontents/ with:
$.get('/admin/import/getcontents/'+ encodeURIComponent($('#urlcheck').val()) ,function(data) {
$('#importtable').html(data);
$('#busy-indicator').fadeOut('high');
});
so I call the page: /admin/import/getcontents/http%3A%2F%2Flocalhost%2Feclipse%2Fanarxeio%2Fexport%2Fcontents%2F
Apache gives me an 404 error. If I call /admin/import/getcontents/1 the page loads correctly. So I figured to pass a ? before the parameter like:
admin/import/getcontents/?http%3A%2F%2Flocalhost%2Feclipse%2Fanarxeio%2Fexport%2Fcontents%2F
Now I don't get a 404 error but $url param in admin_getcontents() is empty. How can I achieve the above?
Thanks
A quick fix would be to triple url encode your url:
// javascript
$.get('/admin/import/getcontents/'+ encodeURIComponent(encodeURIComponent(encodeURIComponent($('#urlcheck').val()))) ,function(data) {
$('#importtable').html(data);
$('#busy-indicator').fadeOut('high');
});
Then url decode it in your php before you use it:
// php
function admin_getcontents($url = null)
{
$url = urldecode(urldecode($url));
$contents = json_decode(file_get_contents(($url)),true);
//some stuff
}
EDIT following comments:
You will need to set up your routing to pass the url parameter. Looking at your setup, it should looking something like:
Router::connect('/admin/import/getcontents/:url', array(
'controller' => 'import',
'action' => 'getcontents',
'admin' => true),
array(
'url' => '(.*)',
'pass' => array('url')
)
);

Resources