Creating a dropdown menu from an array and prepend the array - php

I have an array which I will use for a dropdown in a form. My array is something like this...
$data = ('1' => 'Option 1', '2' => 'Option 2', '3' => 'Options 3')
Now I want to prepend this to the $data array
'' => 'Please select'
How do I do this? I've tried array_unshift but this adds a key to my option which I don't want because of my form validation.
Anyone help?
Thanks

All array values have a key. array_shift is the best way to do this.

You can use union operator
$data = ('1' => 'Option 1', '2' => 'Option 2', '3' => 'Options 3')
$prependArray = array('' => 'Please select');
$result = $prependArray + $data;

Related

Call to a member function toArray() on array

I’m trying to use this package: https://packagist.org/packages/digital-creative/conditional-container. However with this basic example:
return array_merge(
[
Select::make('Option', 'option')
->options([
1 => 'Option 1',
2 => 'Option 2',
3 => 'Option 3',
]),
/**
* Only show field Text::make('Field A') if the value of option is equals 1
*/
ConditionalContainer::make([ Text::make('Field A') ])->if('option = 1'),
Text::make('Title'),
Textarea::make('Description'),
],
$arr
);
I’m getting the error message: Call to a member function toArray() on array.
If I change to:
return array_merge(
[
[
Select::make('Option', 'option')
->options([
1 => 'Option 1',
2 => 'Option 2',
3 => 'Option 3',
]),
ConditionalContainer::make([ Text::make('Field A') ])->if('option = 1')
],
It shows:
message: "Call to a member function getUpdateRules() on array"
even with only the example like below it shows "message: "Call to a member function toArray() on array":
public function definition(): array
{
return [
Select::make('Option', 'option')
->options([
1 => 'Option 1',
2 => 'Option 2',
3 => 'Option 3',
]),
ConditionalContainer::make([ Text::make('Field A') ])->if('option = 1')
];
}
Do you know how to solve the issue? Thanks!
Not sure what is does, but you are sending an array to a class that class has a method toArray().
that's why i always use return types in my code cause it will break if the input does not match.
Could it be that it thinks that this is a collection or a class that needs to be inputted.
in some cases i am lazy and will try the following:
collect(return array_merge(
[
[
Select::make('Option', 'option')
->options([
1 => 'Option 1',
2 => 'Option 2',
3 => 'Option 3',
]),
ConditionalContainer::make([ Text::make('Field A') ])->if('option = 1')
],)
because many packages uses Collection as a way to handle, filter and search an array.
but this is more a guess than actuall knowledge. Look at the function getUpdateRules() in the vendor map, what does it do.
/**
* #param Resource|Model $resource
*
* #return array
*/
public function resolveDependencyFieldUsingResource($resource): array
{
$matched = $this->runConditions(
$this->flattenRelationships($resource)
);
return $matched ? $this->fields->toArray() : [];
}
this is the function so as you can see it expects a model or resource class
according to the docs:
return [
Select::make('Option', 'option')
->options([
1 => 'Option 1',
2 => 'Option 2',
3 => 'Option 3',
]),
//more suff
your return array
array_merge(
[ // <--- note the extra bracket
[
Select::make('Option', 'option')
->options([
1 => 'Option 1',
2 => 'Option 2',
3 => 'Option 3',
]),
ConditionalContainer::make([ Text::make('Field A') ])->if('option = 1')
],

How do I remap my array keys using an array of integers?

Here is my original array of items
$items = [
0 => 'item 1',
1 => 'item 2',
2 => 'item 3'
];
I want to change the order of the items based on their keys, so I'm doing this...
$reorder = [2,0,1];
uksort($items, function($key1, $key2) use ($reorder) {
return (array_search($key1, $reorder) > array_search($key2, $reorder));
});
This works as it should, and produces the proper results.
$items = [
2 => 'item 3',
0 => 'item 1',
1 => 'item 2'
];
However, when returning that in Laravel as json the newly ordered $items reverts back to the original order, which is obviously not what I want.
Is there a way to remap the array keys while reordering them?
How exactly are you returning the array in Laravel? The following example works for me exactly as you want it.
Route::get('/test', function () {
$items = [
0 => 'item 1',
1 => 'item 2',
2 => 'item 3'
];
$reorder = [2,0,1];
uksort($items, function($key1, $key2) use ($reorder) {
return (array_search($key1, $reorder) > array_search($key2, $reorder));
});
return response()->json($items);
// {"2":"item 3","0":"item 1","1":"item 2"}
});
If you have tried it in a browser, keep in mind that some browsers automatically reorder json arrays. In that case you have to get the raw instead of the formatted data.

How to loop through a list of products and categories on PHP

<?
$categoriesID = array("popular","old");
$product => array (
Product 1
'categoryID' => $categoriesID[1],
'Name' => 'Product One',
Product 2
'categoryID' => $categoriesID[2],
'Name' => 'Product Two',
Product 3
'categoryID' => $categoriesID[2],
'Name' => 'Product Two',
Product 4
'categoryID' => $categoriesID[2],
'Name' => 'Product Two',
);
How can I loop through this to reflect that product 1 belongs to category 1, product 2 belongs to category 2, product 3 belongs to category 2 and so on?
I tried the following but no luck..
foreach($product as $key => $pro){
var_dump($categoriesID[$key]);
}
I would really appreciated any suggestions or how what i'm doing wrong.The goal is to insert the relationship into a database table where in order to insert a product a category_id is required.
Your arrays are not written correctly. You got a multi dimensional array here (arrays inside of an array). Read this to understand how they are written and how you can work with them: http://php.net/manual/en/language.types.array.php
If your categories are numeric you should also consider to use numeric values: 1 instead of '1' inside of the $categoriesID array or depending on the database auto casting capability you will get issues inserting strings as decimals.
Here is your given code modified as working example. Ive changed the var_dump output for better readability of the result.
Ive also changed the array indexes you have used since arrays start at 0. If you need the numbers still to start at 1 you could add some nonsense value at the beginning of the array or subtract 1 when accessing the array. Keep in mind that this is an quick & dirty solution to the given problem.
Nevertheless as Patrick Q said you should consider some introduction to PHP.
<?php
$categoriesID = array('1','2');
$product = array (
array(
'categoryID' => $categoriesID[0],
'Name' => 'Product One',
),
array(
'categoryID' => $categoriesID[1],
'Name' => 'Product Two',
),
array(
'categoryID' => $categoriesID[1],
'Name' => 'Product Two',
),
array(
'categoryID' => $categoriesID[1],
'Name' => 'Product Two',
)
);
foreach($product as $key => $value){
echo var_export($value, true) . '<br>';
}
You could further edit Mariusz's answer to do something like this:
foreach($product as $item){
echo $item['Name'].' - '.$item['categoryID'].'<br>';
}
This would give you easy access to both product name and category ID.

Calling PHP Class Public Function Inside Smarty Template

Can someone help me out here.
How can i Call a PHP class public function inside a Smarty template file for example.
I have 2 Functions inside the Movie Class
GetAllMovies(); // Gets all Movies
and
GetMovie($movie_id); // Gets movie by movie id
Now i am calling the GetAllMovies(); and assigning it to the template
<?php
include 'movie.class.php';
$movie = new Movie();
$movies = $movie->GetAllMovies();
$smarty->assign('movies',$movies);
<?
Now inside the template file i've got a foreach statement for the movies.
{foreach from=$movies key=key item=mov}
// Access Movie ID, Title And Images
{/foreach}
Now what i want to do is to call GetMovie($movie_id); inside this foreach statement for example do something like this.
Assign Movie class to Smarty Template.
$smarty->assign('movie',$movie);
Then use $movie to call the function for example
{foreach from=$movies key=key item=mov}
{assign var=movie_info value=$movie::GetMovie($mov.id)}
{$movie_info.rating}
{/foreach}
Could someone please point me in the right direction.
It looks realy creepy but if you realy want to use it in that way, I suggest to create array on PHP side and assing it to smarty like:
$movies = array();
$movie = new Movie();
foreach ($movie->GetAllMovies() as $key => $movieDetails) {
$mov = new Movie();
$movies[] = $mov->getMovie($movieDetails['id']);
}
$smarty->assign('movies',$movies);
and in smarty you can loop thrue your $movies array
{foreach from=$movies key=key item=mov}
{$mov.rating}
{/foreach}
Based on this:
http://www.smarty.net/docs/en/advanced.features.static.classes.tpl
This should work:
{assign var=movie_info value=Movie::GetMovie($mov.id)}
At least if it is an existing static method...
I wouldn't tell you how to do it because it doesn't make any sense for me.
Template engine is for displaying data and you should get data inside Model/Controller. You should assign to Smarty data that is prepared to display and in Smarty you should display it.
So in your case before:
$smarty->assign('movies',$movies);
you should use:
$movies = $movie->GetAllMovies();
foreach ($movies as $k => $v) {
$movies[$k]['details'] = $movie->GetMovie($v['id');
}
and then in Smarty:
{foreach from=$movies key=key item=mov}
{$mov.details.rating}
{/foreach}
However if I were you, I would consider getting data. I assume that you get your movies from Database, so using:
$movies = $movie->GetAllMovies(); // 1 query
foreach ($movies as $k => $v) {
$movies[$k]['details'] = $movie->GetMovie($v['id'); // n queries
}
you run n+1 queries to your database, where n is number of movies.
It's quite possible that instead of this, you could run one query to database (depending on your structure using join or even not) so you should rethink if you get data the best way it's possible.
I think the proper way to do it, would be pulling your movies data in a 'ready-to-display' form, such as an array, associative array or their multidimensional counterparts that smarty can handle right away with the {foreach} tag. Maybe something that looked like:
array (
0 => array ( 0 => 'PHP the Movie 1', 1 => '2009', 2 => 'Coder 1', 3 => '3', ),
1 => array ( 0 => 'PHP the Movie 2', 1 => '2010', 2 => 'Coder 2', 3 => '2', ),
2 => array ( 0 => 'PHP the Movie 3', 1 => '2011', 2 => 'Coder 3', 3 => '1', ),
)
array (
0 => array (
'title' => 'PHP the Movie 1',
'year' => '2009',
'director' => 'Coder 1',
'rating' => '3', ),
1 => array (
'title' => 'PHP the Movie 2',
'year' => '2010',
'director' => 'Coder 2',
'rating' => '2', ),
2 => array (
'title' => 'PHP the Movie 3',
'year' => '2011',
'director' => 'Coder 3',
'rating' => '1', ),
)
array (
0 => array (
'title' => 'PHP the Movie 1',
'year' => '2009',
'director' => 'Coder 1',
'rating' => '3', ),
1 => array (
'title' => 'PHP the Movie 2',
'year' => '2010',
'director' => 'Coder 2',
'rating' => '2', ),
2 => array (
'title' => 'PHP the Movie 3',
'year' => '2011',
'director' => 'Coder 3',
'rating' => '1', ),
)
Only my humble opinion but I actually use it at work both to display data-sets with smarty and to build JSON responses for AJAX requests to the server.
You could use static methods in your movie class.
If for example your class is named "MovieClass" then you could have:
MovieClass::GetMovie($mov.id);
To create a static method just use the following format when declaring the method inside your class
public static GetMovie($mov.id)
{
...
}

Add a multidimension PHP Array at the end of each item of a multidimension array

Here are the two Multi-dimension arrays explained.
// Categories Array
$categories = array(
array('cat_id'=>'1', 'cat_name' => 'Category One', 'cat_data' => 'Some Data'),
array('cat_id'=>'2', 'cat_name' => 'Category Two', 'cat_data' => 'Some Data'),
array('cat_id'=>'3', 'cat_name' => 'Category Tree', 'cat_data' => 'Some Data')
);
// Products Array (One $products array is to be placed inside every new category.
$products = array(
array('p_id'=>'1', 'p_name'=>'Product One'),
array('p_id'=>'2', 'p_name'=>'Product Two'),
array('p_id'=>'3', 'p_name'=>'Product Three')
);
Here The $products needs to be placed inside every element of $category array, with a key of some random key take for eg 'product_list'.
Here is the result like
$category = array(
array('cat_id'=>'1', 'cat_name' => 'Category One', 'cat_data' => 'Some Data', 'product_list'=>array()),
array('cat_id'=>'2', 'cat_name' => 'Category Two', 'cat_data' => 'Some Data', 'product_list'=>array())
);
Please scroll Right for the above code to see the last element added to these elements.
Please tell how to add that multi-dimension array with a key to each n every element of the $category array. Thanks
What is the problem?
foreach ($categories as &$category) {
$category['product_list'] = $products;
}
Try to use this code.
foreach($categories as $key=>$value)
{
$categories[$key]['product_list'] = $products;
}
After trying several attemps, I solved this problem by myself by just a simple code. here it is.
$categories['product_list'] = $products;
Hope, users finding this type of problem this useful. Thanks

Categories