codeigniter associative array in post - codeigniter

I normally name my db specific fields in my forms like this "objectname[columnname]", I tseems CI cant access these values using $this->input->post('objectname[columnname]'), what do I do? there is not a chance in hell im renaming 100+ form fields.. I am actually disliking CI, it really is getting in the way of progress by changing the de facto PHP norms...

And were you using $_POST['objectname[columnname]'] or $_POST['objectname']['columnname'] ?
Have you tried the equivalent for the latter
$obj = $this->input->post('objectname');
echo $obj['columnname'];
?
If it works, you can write you own helper to retreive that like post_val('objectname[columnname]').

I saw this post whilst looking for a similar issue, but worked out a CI way to do it, sorry if I'm resurrecting it, but it does appear fairly high on the Google results.
// Load the 'array' helper
$this->load->helper('array');
// Use the 'element' function to return an element from the array
echo element('ColumnName', $this->input->post('ObjectName'));
Hope this helps anyone who comes here in future.

HTML code:
<input type="text" value="" name="myPostArrayName[]">
<input type="text" value="" name="myPostArrayName[]">
Handling form with codeigniter:
$data = $this->input->post('myPostArrayName', TRUE);
You can access data in order like this
echo 'Value of the first element in the form array is '.$data[0];
echo 'Value of the second element in the form array is '.$data[1];
I think someone who has access to codeigniter documentation, had better to add a simple html post array handling example.

I seems I can rely on the $_POST var, but I thought this was reset?

You can cast the post array as an object and use method chaining to return sub-arrays (now properties) using PHP 5.3's method chaining all on one line.
Extend the input class by making a class called MY_Input and put the extended class in the application/core folder. CI 2.0 will automatically use the extended class with the MY_ prefix, and you can add methods to this new class. Extending the input class is cleaner than making helpers.
This method casts the post array, or a nested array (a sub array below the parent), as an object.
/* Cast an array from CI post as an object and return the object */
public function post_obj($key = null){
$post_return = $this->post($key);
if (false === $post_return)
return false;
return (object)$post_return;
}
Now I can retrieve nested values in one line of code using PHP 5.3's method chaining for objects.
$active = $this->input->post_obj('user')->active;

I just went with the $_POST['objectname']['colname'] option as i usually do even though this is probably not the CI way..

Related

Construct routes(urls) with slugs separated by dash in laravel

I am about to make more SEO-friendly URLs on my page and want a pattern looking like this for my products:
www.example.com/product-category/a-pretty-long-seo-friendly-product-name-12
So what are we looking at here?
www.example.com/{slug1}/{slug2}-{id}
The only thing I will care about from the URL in my controller is the {id}. The rest two slugs are just of SEO purpose. So to my question. How can I get the 12 from a-pretty-long-seo-friendly-product-name-12?
I have tried www.mydomain.com/{slug}/{slug}-{id} and in my controller to try and get $id. Id does not work. I am not able to able to separate it from from a-pretty-long-seo-friendly-product-name. So in my controller no matter how I do I get {slug2} and {id} concatenated.
Coming from rails it is a piece of cake there but can't seem to figure out how to do that here in laravel.
EDIT:
I am sorry I formulated my question very unclear. I am looking for a way to do this in the routes file. Like in rails.
You're on the right track, but you can't really logically separate /{slug}-{id} if you're using dash-separated strings. To handle this, you can simply explode the chunks and select the last one:
// routes/web.php
Route::get('/{primarySlug}/{secondarySlugAndId}', [ExampleController::class, 'example']);
// ExampleController.php
public function example($primarySlug, $secondarySlugAndId){
$parts = collect(explode('-', $secondarySlugAndId));
$id = $parts->last();
$secondarySlug = $parts->slice(0, -1)->implode('-');
... // Do anything else you need to do
}
Given the URL example.com/primary-slug/secondary-slug-99, you would have the following variables:
dd($primarySlug, $secondarySlug, $id);
// "primary-slug"
// "secondary-slug"
// "99"
The only case this wouldn't work for is if your id had a dash in it, but that's another layer of complexity that I hope you don't have to handle.
Route::get('/test/{slug1}/{slug2}','IndexController#index');
public function index($slug1, $slug2)
{
$id_slug = last(explode('-',$slug2));
$second_slug = str_replace('-'.$id_slug,'',$slug2);
dd($slug1, $second_slug,$id_slug);
}

Laravel 5.1 translate an array pass to blade

I have this in my controller
public function editProfile(Request $request){
$question1 = Question::where('group',1)->lists('question', 'id');
$question2 = Question::where('group',2)->lists('question', 'id');
return view('user', compact(''question1', 'question2'));
}
$question = {\"1\":\"What is the first name of your best friend in high school?\",\"2\":\"What was the name of your first pet?\",\"3\":\"What was the first thing you learned to cook?\",\"4\":\"What was the first film you saw in the theater?\"}
$question2 = {\"5\":\"Where did you go the first time you flew on a plane?\",\"6\":\"What is the last name of your favorite elementary school teacher?\",\"7\":\"In What city or town does your nearest sibling live?\"}
I would like to translate the value in both question 1 and question 2 and pass it to user blade without changing the key, Any suggestions?
As specified at the localization doc, you need to populate a lang file with translation strings. So, let's say you want to show both Spanish and English strings. In this case you'd need to create two files: /resources/lang/en/messages.php and /resources/lang/es/messages.php. The content of one of those files would be somewhat like this:
<?php
// resources/lang/es/messages.php
return [
'welcome' => 'Bienvenido'
];
This way, you could access the strings in there with the following method: __('messages.welcome'), which would return the string for the language set on your config/app.php -- the default entry is en, by the way, but you can set it to whatever you want. The value in there will define which language will be chosen when selecting strings.
Another method to create translation strings is using the string itself as key, storing them in a JSON file instead of PHP. For example, the following translation string:
{
"I love programming.": "Me encanta programar."
}
would be accessible through this: __('I love programming.').
Having said that, you may solve your problem through the two methods presented above. You could store in your DB keywords for the questions instead of the whole text, and create translation for as many languages as you want. Also, you could keep the questions in your database and create translation strings for those questions. Finally, you'd need to iterate over the fetched entries and translate each one of them, or use some Collection helper to do the hard work for you, like transform or map.

Request::has() returns false even when parameter is present

URL: http://localhost/?v=
Code:
Route::get('/', ['as' => 'home', function()
{
dd(Request::has('v'));
}]);
Output: false
What is going on? Is this a bug or am I doing something wrong?
Request::has() will check if the item is actually set. An empty string doesn't count here.
What you are looking for instead is: Request::exists()!
Route::get('/', ['as' => 'home', function()
{
dd(Request::exists('v'));
}]);
tl;dr
Upgrade to Laravel 5.5 or higher. They changed this so now it works as you originally expected.
Explanation
In the Laravel 5.5 upgrade guide, we read the following:
The has Method
The $request->has() method will now return true even if the input value is an empty string or null. A new $request->filled() method has been added that provides the previous behaviour of the has() method.
The $request->exists() method still works, it is just an alias for $request->has().
Examining the source code
In Laravel 5.4:
$request->exists(): Determine if the request contains a given input item key.
$request->has(): Determine if the request contains a non-empty value for an input item.
In Laravel 5.5:
$request->exists(): Alias for $request->has
$request->has(): Determine if the request contains a given input item key.
$request->filled(): Determine if the request contains a non-empty value for an input item.
If you click to the commands above, you can check out the source code and see that they literally just renamed exists to has, has to filled, then aliased exists to has.
Use Request::filled() because unlike Request::has(), it also checks if the parameter is not empty.
You might wanna check this out. since the $request->has() method and it property can offer access to request origin.
It's ok to use $request->has('username') This will check if <input type="text" name="username" /> username attributes actually exist or the params/.query string actually have that key on the request global.
As to me it's not a bug, but feature :) In your example v is provided, but it's empty.
In framework code you'll find this:
if ($this->isEmptyString($value)) return false;
So, if empty string is provided has() method will return false. It makes sense to me, in most cases I want this behavior.

Looking for a easier cleaner way to save ajax POST data to a django model and avoid hardcoding for saving?

I have been working on a django project that requires a large amount of user input and processing and am sick of hardcoding the data in the view in order to save it to my models as seen below.
mymodel = TheModel.objects.get(id=model.id)
mymodel.name = request.POST.get('name')
mymodel.zip = request.POST.get('zip')
...
mymodel.save()
Except instead of two model attributes like I used above there are sometimes up to 25 that need to be saved.
I am using ajax to serialize the forms and send them to my views where they are saved. I am looking for the cleanest way possible to get around this problem. Less code the better and I am willing to reformat my models if there is a way that significantly shortens the number of lines of code I have now.
Thanks
you may want to have a look at ModelForms
This method will work, although you have to be careful to add a model field / ajax parameter at the sametime for it to work
Given:
Form1
<form method="post">
<input name="parameter1" />
<input name="parameter2" />
<input name="parameter3" />
</form>
Write javascript code so the data going across the wire looks like this JSON (form serialization
will probably not work)
{ parameter1 : "some data", "parameter2" : "some data", parameter3 : "some data" }
Then, you have a django model that looks like this
class MyModel(models.Model):
parameter1 = models.StringField()
parameter2 = models.StringField()
parameter3 = models.StringField()
You can save/update with code like this:
params = dict(request.POST)
m = MyModel.objects.create(**params)
or
m = MyModel.objects.get(id=ID)
m.update(force_update=False,**params)
If your parameters do not line up the code will fail though.

Mutliple URL Segments to Index Function With CodeIgniter

Please excuse me if this is an incredibly stupid question, as I'm new to CodeIgniter.
I have a controller for my verification system called Verify. I'd like to be able to use it something like site.com/verify/123/abcd, but I only want to use the index function, so both URL segments need to go to it.
I'm sure this can be done with URL routing somehow, but I can't figure out how to pass both URL segments into Verify's index function..
Something like this in routes.php should do the job:
$route['verify/(:any)/(:any)'] = "verify/index/$1/$2";
I'm pretty sure you can just pass any controller method in CodeIgniter multiple arguments without modifying routes or .htaccess unless I misunderstood the problem.
function index($arg_one, $arg_two)
{
}
$arg_one representing the 123 and $arg_two representing the abcd in your example URI.
You will either need to edit the routes or write an htaccess rule, however i didn't understand why you want to limit to just the index function.
If you didnt wanna use routes for some reason, then you could add this function to the controller in question.
public function _remap($method_in, $params = array()) {
$method = 'process_'.$method_in;
if (method_exists($this, $method)) {
return call_user_func_array(array($this, $method), $params);
}
array_unshift($params, $method_in);
$this->index($params);
}
Basically it does the same as default behavior in CI, except instead of sending a 404 on 'cant find method', it sends unfound method calls to the index.
You would need to alter your index function to take an array as the first argument.
OR if you know that you only ever want 2 arguments, you could change the last 2 lines to
$this->index($method_in, $params[0]);
Of course both solutions fail in someone uses an argument which is the same as a method in your controller.

Resources