ROUTE PARAMETER DISAPPEAR AFTER SAVE DATA - php

Hi everyone I need help with this problem. I am programming an application using php with laravel framework. My current laravel framework version is 4.2.11
I have this route to handle POST & GET actions
Route::any("/myaccount2/ausersave/{code?}", array("as" => "ausersave",
"uses" => "PrivateController#ausersave"))->before('auth_admin');
When I use Get action with mydomain/myaccount2/ausersave/90
I get list all data ok. But when I post all data to save the url change to mydomain/myaccount2/ausersave (parameter 90 is missing)
I guest this change is before the data is saved because the {code?} or 90 parameter is missing.
So I was looking for a function that allowed my application to post data and keeps the old url (mydomain/myaccount2/ausersave/90)
I find this function Redirect::back() but some post don't recommend to use it
I will apreciate your help. Thanks
My controller function is:
public function ausersave($code = 'null') {
$messg = null;
if(Input::get("userid") != null && Input::get("personid") != null) {
return View::make('PrivateController.ausersave', array('message' =>'Ok',
'user' => null, 'children' => null));
}
else if(isset($code)) {
return View::make('PrivateController.ausersave',
$this->ausersaveGet($code) );
}
return View::make('PrivateController.ausersave',
array('message' => '', 'user' => null,
'children' => null));
}
$this->ausersaveGet($code) -> this function bring me data form database and return me an array with thosse values array('message' => '', 'user' => $user, 'children' => $children); where user has info about user and children is an array of data. All this data return ok.

I would try taking the the ? out of the route parameter. i.e. change this:
Route::any("/myaccount2/ausersave/{code?}", array(......
to this:
Route::any("/myaccount2/ausersave/{code}", array(......

Related

Use register_rest_field inside a custom route

I'm currently trying to create an API which will be used to create an app
To do this I need a custom endpoint which should be accessed only from a logged user, which is currently done using this code:
register_rest_route( 'wp/v2', 'private/me',array(
'methods' => WP_REST_Server::READABLE,
'callback' => 'get_private'
));
function get_private($request) {
$user = (array) wp_get_current_user();
$user["data"] = (array) $user["data"];
unset($user['data']['user_pass']);
// $user = get_user_by('id', 13);
if (empty($user)) {
return new WP_Error( 'empty_category', 'there is no post in this category', array('status' => 404) );
}
$response = new WP_REST_Response($user['data']);
$response->set_status(200);
return $response;
}
Currently it return an user object without 'user_pass'
Then when I use the 'register_rest_field' function, I get nothing (the function work if set on any default api user endpoint
register_rest_field('private/me',
'rank_number',
array(
'get_callback' => 'get_rank_number',
'update_callback' => null,
'schema' => null
)
);
function get_rank_number ( $user ) {
return (int) get_user_meta($user['id'], 'ck_user_ranking_score_number', true);
}
The thing is, I don't know how to make the route read the list of the registered rest fields nor if it's supposed to be done like that
Currently, I'm trying to make it by extending the WP_REST_Controller class since it looks like it could work
Can someone help me understand how the API work or how it is supposed to be used ? :/
In case anyone have the same problem, a wordpress user answered my post on their forum,
Solution:
The var $wp_rest_additional_fields, I can't find anything about it in the documentation, but at least the var really exist in the global scope
So with this code everything's ok
global $wp_rest_additional_fields;
foreach($wp_rest_additional_fields['private/me'] as $key => $value){
$user_data[$key] = call_user_func($value['get_callback'], $user['data']);
}

Laravel 5.1 - Return to edit page

i'm writing a resource controller, and i have a problem with edit method.
i inserted a validator form, and if there is a error return to edit page with messages, but RETURN doesnt work good!
public function update(Request $request, $id)
{
$rules = [
'title' => 'required',
'content' => 'required',
'image' => 'required',
];
$messages = [
'title.required' => 'Campo titolo richiesto',
'content.required' => 'Contenuto richiesto',
'image.required' => 'Campo immagine richiesto',
];
$validator = Validator::make($request->all(), $rules, $messages);
if ($validator->fails()){
return redirect('admin/article/edit' , $id)->withErrors($validator);
}else {
$s = new Article;
$visible = (isset($_POST['visible']) == '1' ? '1' : '0');
$data = array(
'title' => $request->get('title'),
'slug' => $request->get('title'),
'content' => $request->get('content'),
'image' => $request->get('image'),
'user_id' => $request->get('user_id'),
'category_id' => $request->get('category_id'),
'visible' => $visible,
);
$s->where('id', '=', $id)->update($data);
return redirect('admin/article')->with('message', 'Articolo aggiornato con successo!');
}
}
It return to:
admin/article/edit/5
NOT to
admin/article/5/edit
How can i fix this issue? thank you for your help!
PS: $id work well, return my id edited
Here is the redirect helper. As you can see below, it takes status as its' second parameter.
function redirect($to = null, $status = 302, $headers = [], $secure = null)
What you do with passing the $id as the second parameter is actually setting the $status.
You need to pass the $to parameter as the full path like below.
return redirect('admin/article/' . $id . '/edit')->withErrors($validator);
I guess that you want to generate the url with route, which can be implemented like below.
return redirect(route('admin.article.edit', compact($id)))->withErrors($validator);
So you're saying the redirect on failure doesn't redirect to the right URL? Have you tried doing return redirect('admin/article/' . $id . '/edit')->withErrors($validator);?
I haven't tested this approach, but perhaps return redirect()->back()->withErrors($validator); could also work.
One way to do this, as others have suggested, is like following:
return redirect("admin/article/{$id}/edit")->withErrors($validator);
Or if you've a "Route Name" defined, like this..
return redirect()->route('route.name',[$id])->withErrors($validator);
it all depends on how you prefer, I prefer the later one, looks clean to me.
Easiest solution:
Laravel 5.1 has a back() helper, that returns to the previous page:
return back()->withErrors($validator);
More thorough explanation:
If you want to be more verbose, a generally more robust way to redirect to a route is to first define it as a named route in your routes.php:
Route::get('admin/article/{article_id}/edit', ['as' => 'articles.edit', 'uses' => 'ArticlesController#edit']);
Route::bind('article_id', function($id, $route) {
return App\Article::whereId($id)->findOrFail();
}
If you are using Route::resource instead, then this is already done automatically for you. To find the name of the route, run the command-line php artisan route:list. Then, in your controller method, you call it like this:
return redirect()->route('articles.edit', ['article_id' => $id])->withErrors($validator);
Using that kind of call, Laravel will automatically build the correct URL for you. This is more robust because if you ever want to change that URL to something else or change what controller method it calls, you only need to change it in one place, the routes.php, and not everywhere in your code (as long as every reference to that route in your code is referring to it by name).
Here you have
return redirect('admin/article/edit' , $id)->withErrors($validator);
means the link/route is admin/article/edit/$id(5 or 2 or ...)
better check
return redirect('admin/article/' . $id . '/edit')->withErrors($validator);
The redirect go to the passed url:
return redirect('admin/article/' . $id . '/edit'); #admin/article/id/edit
return redirect('admin/article/edit', $id); #admin/article/edit/5
And you can use methods to get this url:
return redirect(action('Controller#update', compact($id)));

Laravel 4: Unique(database) not validating

I am creating a basic CMS to teach myself the fundamentals of Laravel and PHP.
I have a 'pages' table and I am storing a url_title. I want this URL title to be unique for obvious reasons. However, whatever I do to validate it, fails. It just saves anyway. I'm sure it is something simple. Can you spot what is wrong with this code?
I am also using Former in the view, that doesn't validate either. I have tried hard-coding a value as the last option in the unique method and it fails also.
http://anahkiasen.github.io/former/
http://laravel.com/docs/validation#rule-unique
States: unique:table,column,except,idColumn
Here is my Controller:
public function store()
{
$validation = Pages::validate(Input::all());
if($validation->fails()) {
Former::withErrors($validation);
return View::make('myview');
} else {
Pages::create(array(
'title' => Input::get('title'),
'url_title' => Input::get('url_title'),
'status' => Input::get('status'),
'body' => Input::get('body'),
'seo_title' => Input::get('seo_title'),
'seo_description' => Input::get('seo_description')
));
//check which submit was clicked on
if(Input::get('save')) {
return Redirect::route('admin_pages')->with('message', 'Woo-hoo! page was created successfully!')->with('message_status', 'success');
}
elseif(Input::get('continue')) {
$id = $page->id;
return Redirect::route('admin_pages_edit', $id)->with('message', 'Woo-hoo! page was created successfully!')->with('message_status', 'success');
}
}
}
Here is my model:
class Pages extends Eloquent {
protected $guarded = array('id');
public static $rules = array(
'id' => 'unique:pages,url_title,{{$id}}'
);
public static function validate($data) {
return Validator::make($data, static::$rules);
}
}
I have tried the following:
public static $rules = array(
// 'id'=> 'unique:pages,url_title,{{$id}}'
// 'id'=> 'unique:pages,url_title,$id'
// 'id'=> 'unique:pages,url_title,:id'
// 'id'=> 'unique:pages,url_title,'. {{$id}}
// 'id'=> 'unique:pages,url_title,'. $id
);
Any ideas? I spoke to the guy who created Former. He can't make head nor tail about it either. He suggested tracking it back to find our what query Laravel uses to check the uniqueness and try running that directly in my DB to see what happens. I can't find the query to do this. Does anyone know where to track it down?
Many thanks
Your rule should be:
public static $rules = array(
'url_title' => 'unique:pages,url_title,{{$id}}'
);
As I guessed from your code Input::get('url_title')
You have to use the field name used in the form.
Thanks peeps. I have been using the Laravel unique solutions and it hasn't been working well. I found this package which solves the issue brilliantly.
https://github.com/cviebrock/eloquent-sluggable#eloquent
Definitely worth a look.
Thanks for your feedback.

What is AuthComponent::getModel() alternative in cakePHP2x?

I am using a Remember Me Component. Actually, migrating a CakePHP 1.3 app to CakePHP 2x. I am stuck with this LAST PIECE of code that is RememberMeComponent.
The script which I see here to SET the cookie is :
function make( ) {
$data = array(
$this->ident_field => $this->_create_token( ),
$this->token_field => $this->_create_token( ),
);
$this->Cookie->name = $this->cookie_name;
$this->Cookie->time = $this->period;
$this->Cookie->key = base64url_encode(implode('::', $data));
$this->Cookie->secure = true;
$this->Auth->getModel()->save(array($this->Auth->userModel => array_merge(array('id' => $this->Auth->user('id')), $data)), false);
}
and checks with :
function check( ) {
$cookie = $this->Cookie->read($this->cookie_name);
if (empty($cookie)) {
return false;
}
$data = explode('::', base64url_decode($cookie));
$user = $this->Auth->getModel( )->find('first', array(
'conditions' => array(
$this->Auth->userModel.'.ident' => $data[0],
),
));
if ( ! $user) {
return false;
}
function base64url_encode is defined in bootstrap - so, it is valid function.
Now there is line:
$this->Auth->getModel()->save(array($this->Auth->userModel => array_merge(array('id' => $this->Auth->user('id')), $data)), false);
That is giving me an error:
Error: Call to undefined method AuthComponent::getModel()
File: /var/www/FlintStones/Controller/Component/RememberMeComponent.php
I checked Auth Component documentation but, it did not have any option where I could find the model for auth.
Thanks in advance.
PS: We cannot directly move to Auto Login (as you might have that in mind) or if you can also refer to a quick-step-by-step, please share. I might even consider that but, so far it is just to get the Auth model.
I had the same issue in the same component.
How to get $settings data out of CakePHP 2.0 FormAuthenticate object
Summary:
Use $this->Auth->userModel to get the model. If the value is null, it will default to 'User'.

Difference between Controller and Model in MVC

I'm little confused about controller and model in MVC framework (codeIgniter). Its clear to me that controller methods calls the views and Model methods interact with database.
However, I'm little confused about the following types of methods, which are called by methods in a controller.
hash_password //returns hash password.
valid_email //validates email format and return true or false
is_logged //check if session has a variable, returns true or false
generate_random_string //generates and hashes a random string
Should they be placed in controller or in a model?
Currently I place all of the above functions in a controller. Is it correct?
I think the is_logged should be placed in the Model for User. Note that the User might be a customer in your case or any class that you have made to model a user of your service.
The valid_email and generate_random_string are more or less utility functions, which you can place in a Utility or Utilities model, so that these are reusable in various controllers in your application.
The hash_password, can be placed in either the User model or Utility model. I am more tempted to place it in Utility model, since its a hashing function and there is nothing the user cares about. However, I can imagine there can be argument(s) otherwise.
The following SO question (though for a different framework) can also serve as a rule of thumb:
Where to put custom functions in Zend Framework 1.10
generally controllers are used to determine how to handle the http requests made..
There's nothing wrong in creating some functions which directly respond to the http requests.
but if it has anything to do with the DB, its better to place those function in the model, and call them from the controller.
Controller should combine view with model, so every validation shoulde be placed in model
this is my example from kohana
CONTROLLER
<?php
/**
* User Controller
*/
class Controller_Admin_User extends Controller_Admin_Template {
public function action_index()
{
$this->template->body = View::factory('admin/user/index')
->set('i', 0)
->bind('users', $users)
->bind('groups', $groups)
->bind('id_user_group', $id_user_group);
$model_user = new Model_Admin_User;
$users = $model_user->get_users(Arr::get($_GET, 'sort'), Arr::get($_GET, 'order'));
$model_usergroup = new Model_Admin_Usergroup;
$groups = $model_usergroup->get_user_group();
}
public function action_add()
{
$this->template->body = View::factory('admin/user/form_add')
->bind('error', $error)
->bind('groups', $groups)
->bind('post', $post);
$model_usergroup = new Model_Admin_Usergroup;
$groups = $model_usergroup->get_user_group();
if($_POST)
{
$model_user = new Model_Admin_User;
if($model_user->save($_POST) == false)
{
$error = $model_user->error;
$post = $_POST;
}
else
{
$this->request->redirect('admin/user');
}
}
}
MODEL
class Model_Back_User extends Model {
private $qb;
public $aliases = array(
'id'=> 'id_user'
);
public $error = array(
'name' => null,
'surname' => null,
'login' => null,
'password' => null,
'id_user_group' => null,
'old_password' => null,
'new_password' => null,
'confirm' => null,
'email' => null,
'phone' => null,
);
private $rules = array(
'name' => array('not_empty' => null, 'alpha' => null),
'surname' => array('not_empty' => null, 'alpha' => null),
'login' => array('not_empty' => null),
'password' => array('not_empty' => null),
'id_user_group' => array('not_empty' => null),
'email' => array('not_empty' => null, 'email' => null),
'phone' => array('not_empty' => null),
'old_password' => array('not_empty' => null),
'new_password' => array('not_empty' => null),
'confirm' => array('matches' => array('new_password'))
);
public function __construct()
{
$this->qb = new Querybuilder;
//parent::__construct();
}
public function change_password($data)
{
$validate = Validate::factory($data)
->filter(true, 'trim')
->rules('old_password', $this->rules['old_password'])
->rules('new_password', $this->rules['new_password'])
->rules('confirm', $this->rules['confirm'])
->callback('old_password', array($this, 'password_exists'), array('id_user'=> $data['id_user']));
if($validate->check() == false)
{
$this->error = array_merge($this->error, $validate->errors('user'));
return false;
}
$u = Session::instance()->get('user');
$this->edit(array('password'=> $this->password($data['new_password'])), array('id_user'=> $u['id_user']));
return true;
}
public function password_exists(Validate $valid, $field, $param)
{
if($this->user_exists(array('password'=> $this->password($valid[$field]), 'id_user'=> $param['id_user'])) == false)
{
$valid->error($field, 'old password is incorrect', array($valid[$field]));
}
}
public function save($data)
{
$validate = Validate::factory($data)
->filter(true, 'trim')
->rules('name', $this->rules['name'])
->rules('surname', $this->rules['surname'])
->rules('user_group_id', $this->rules['id_user_group'])
->rules('email', $this->rules['email'])
->rules('phone', $this->rules['phone']);
$edit = false;
if(isset($data['id_user']) AND Validate::not_empty($data['id_user']))
{
$edit = true;
}
else
{
$validate->rules('login', $this->rules['login'])
->rules('password', $this->rules['password']);
}
if($validate->check() == false)
{
$this->error = array_merge($this->error, $validate->errors('user'));
return false;
}
if($edit == true)
{
$this->edit(
array(
'name' => $data['name'],
'user_group_id' => $data['user_group_id']
),
array(
'id_user'=> $data['id_user']
)
);
return true;
}
return $this->add(
array(
'name' => $data['name'],
'login' => $data['login'],
'password' => $data['password'],
'user_group_id' => $data['user_group_id']
)
);
}
protected function add($data)
{
$data['password'] = $this->password($data['password']);
return $this->_db->query(Database::INSERT,
$this->qb->insert('user')->set($data)->build_query()
);
}
View is not so important thats why i dont put this here.
Generally speaking - a model should know stuff about it's own data. So anything related purely to a model's own data - should go in the model.
Eg the hash_password and email-validation methods - a model should know how to validate or update it's own data-fields, so those should go in the model.
However a controller should know about how to direct user actions appropriately and to load the correct models for views etc.
EG the session-related method should go in the controller, because the session is used for storing the user's state (based on past actions).
The "generate random string" method is very vague and may be used everywhere. I'd put that in a separate library possibly included in the model/controller as appropriate.
I've been using Codeigniter for a long time and I'd do the following with your functions as far as placement goes:
hash_password //returns hash password.
I'd put something like a password hasher in a library or helper file so I could call it from my controller like:
// pretend library I'd make for tasks like hashing etc
$this->load->library('passwords');
// transform posted password into it's hashed version
$password = $this->password_library->hash_password($this->input->post('password'));
I'm assuming you want to hash/salt the password and store it in your database in that example
valid_email //validates email format and return true or false
This is already in form_validation, so...
is_logged //check if session has a variable, returns true or false
This should also connect to a authentication library
generate_random_string //generates and hashes a random string
Again, this would come from a library or helper.
SO WHEN DO YOU USE A MODEL?
Me, I use models exclusively for in/out on the database. All my queries go in there. I usually have my model's functions return data objects so I can loop through them in my views.
Controllers call your data from your models, then dump everything into your views. Outside functionality always goes into libraries and helpers. I like to do the "MY_library" and extend Codeigniter's own stuff - especially with forms and the html helper etc.

Categories