how to update wordpress options from multi dimentional array - arrays

Im working on a theme for wordrpess where i want to add an option admin page for the theme settings. Cant get my brain to work with the process. heres my code:
$option_settings = (array(
array('Section1', array(
array( 'ID'=>'id_name1',
'Label'=>'Title1',
'Value'=>'The title1 bar',
'Desc'=>'Description Goes Here1',
'Type'=>'input_text',
'Button'=>'upload'
),
array('Section2', array(
array( 'ID'=>'id_name2',
'Label'=>'Title2',
'Value'=>'The title2 bar',
'Desc'=>'Description Goes Here2',
'Type'=>'input_text',
'Button'=>'upload'
),
))
));
if (!get_option('my_option_settings')) {
add_option('my_option_settings',$option_settings);
}
$options = get_option('my_option_settings');
if ($_REQUEST['save_settings']) {
//this is where my brain snaps huhu
}
echo '<form method="post" action="index.php" id="form_settings">';
echo '<p class="submit message"><input type="submit" value="Save Changes" name="save_settings" /></p>';
foreach ($options as $section) {
echo '<h3>'.$section[0].'</h3>';
foreach ($section[1] as $option => $value) {
switch($value['Type']) {
case "input_text":
echo '<p><strong>'.$value[Label].'</strong> <input type="text" name="'.$value['ID'].'" id="'.$value['ID'].'" value="'.$value['Value'].'" /></p>';
break;
}
}
echo '</form>';
my main concern here is how do i edit array inside an array and how to pass thru request. Any help is much appreciated Thanks in advance.
Updated question:
ok lets say that the $option-settings is the content of the options database from wordpress. The reason is i would like to have just 1 options in wordpress database and just store them thru array for more organize data.
first is get the value and assign it to a variable:
$fetchOption = get_option('my_option_settings');
now i will edit or update the array inside $fetchOption variable.
foreach ($options as $section) {
foreach ($section[1] as $option => $value) {
$value['Value'] = [$_POST[$value['ID']]];
}
}
Last is how to put back the changed value into the $fetchOption variable and update back the database using update_options('my_option_settings', $fetchOption).
Is this appropriate or not? whats the best practice for this? I could just assign them to 1 option but its kinda messy i guess. thanks again!

Uhm. I really hope you already found an answer, but..since someone could need this info I'd like to add it here.
First of all, the link to the resource.
Then, the answer I'm using as a "source":
As far WordPress is concerned - your multi-dimensional array is one option.
To update just part of the multi-dimensional array its necessary to retrieve the entire array, alter it accordingly and then update the entire array.
Suppose your multi-dimensional array is as follows:
my_options = array(
'option_a'=>'value_a',
'option_b'=>'value_b',
'inner_array'=>array(
'foo' => 'bar',
'hello' => 'world',
),
'option_c'=>'value_c'
)
And suppose you want to update the value of the 'hello' option from 'world' to 'moon'
//Get entire array
$my_options = get_option('my_options');
//Alter the options array appropriately
$my_options['inner_array']['hello'] = 'moon';
//Update entire array
update_option('my_options', $my_options);
Hope this helps Stackoverflow visitors in managing multidimensional arrays when it comes to Wordpress options :)

this example can help you;
<div class="ui grid">
<div class="four wide column">
<?php
if (isset($_POST)) {
if (isset($_POST['location']) && !empty($_POST['location'])) {
$locationArray = [];
// this line of code checks if the option is an array or not
$locationArray = is_array(get_option('book_location')) ? get_option('book_location') : [];
// In case of multidimentional array you can push array to an array
array_push($locationArray, $_POST['location']);
// print_r($locationArray);
update_option('book_location', $locationArray);
}
}
?>
</div>
<div class="eight wide column">
<form class="ui form" method="post">
<div class="red card">
<div class="content">
<!-- <div class="header">Bird Name</div>
<div class="meta">
<span class="category">location</span>
</div> -->
<div class="description">
<div class="field">
<label>Location</label>
<input type="text" name="location" placeholder="Location Name">
</div>
</div>
</div>
<div class="extra content">
<div class="ui divider"></div>
<div class="right floated author">
<button class="ui button" type="submit">Add Location</button>
</div>
</div>
</div>
</form>
</div>
<div class="four wide column">
</div>
</div>

Related

Pass multiple variables in laravel foreach loop [duplicate]

This question already has answers here:
Two arrays in foreach loop
(24 answers)
Closed 2 years ago.
So what I am trying to do is create an FAQ accordion but use a #foreach loop and not copy and paste the entire list. My controller code looks like this:
public function faq(){
$faqs=array(
'questions' => ['question1','question2','question3'],
'answers' => ['answer1','answer2','answer3'],
'counts' => ['One','Two','Three']
);
return view('frontend.pages.faq')->with($faqs);
}
This is what I wish to achieve:
#foreach($questions as $question && $answers as $answer && $counts as $count)
<div id="accordion">
<div class="card card--faq mb-2">
<div class="bdv-btn card-header" id="heading{{$count}}">
<h5 class="mb-0">
<a class="btn btn-link w-100" data-toggle="collapse" data-target="#collapse{{$count}}" aria-controls="collapse{{$count}}">
{{$question}}
</a>
</h5>
</div>
</div>
</div>
<div id="collapse{{$count}}" class="collapse" aria-labelledby="heading{{$count}}" data-parent="#accordion">
<div class="card-body bg-light">
{{$answer}}
</div>
</div>
</div>
#endforeach()
In case of the $counts variable the reason I am not using $key instead is that I wish to achieve One, Two, Three and not 1, 2, 3.
The code above is of course in correct. What would be the best way to achieve this? Is it even possible?
you cant access your faq variable in your blade like this, due the wrong usage of with. you should do this:
return view('frontend.page.faq')->with(['faqs'=>$faq]);
first of all do this in your controller:
public function faq(){
$faqs=array(
'questions' => ['question1','question2','question3'],
'answers' => ['answer1','answer2','answer3'],
'counts' => ['One','Two','Three']
);
return view(frontend.page.faq')->with(['faqs'=>$faqs]);
}
then in your blade you can access them like so:
#foreach($faqs['questions'] as $question)
{{dd($question)}}
#endforeach
now you have your faqs in your blade

Retrieving data from an array, starting with specific nth item in Laravel

I have these arrays inside Controller:
Public function home(){
$images = [
'img/image1.jpg',
'img/image2.jpg',
'img/image3.jpg',
'img/image4.jpg',
'img/image5.jpg',
'img/image6.jpg'
];
$rep_titles = [
'外国美女路亚鲈鱼图片合集',
'对人类有威胁的那些怪鱼 高清钓鱼图片',
'那些被钓到的长牙的鱼 高清图片',
'那些钓友去年钓上的巨物 高清图片',
'垂钓图片 那些痴迷的美女',
'冒雨征战秘密基地收获鳊鱼大板鲫',
],
}
and this, inside view:
1ST Content
#foreach (array_slice($images,0,3) as $keyIndex => $image)
<div class="r-c-collection-container">
<div class="img-content">
<img src="{{ asset( $image ) }}" alt="{{ $image }}">
</div>
<div class="r-c-content">
{{$rep_titles[$keyIndex]}}
</div>
</div>
#endforeach
2nd Content (where I want to start on a specific nth-item from the array, 3rd to be specific)
#foreach (array_slice($images,3,3) as $keyIndex => $image)
<div class="r-c-collection-container">
<div class="img-content">
<img src="{{ asset( $image ) }}" alt="{{ $image }}">
</div>
<div class="r-c-content">
{{$rep_titles[$keyIndex]}}
</div>
</div>
#endforeach
My problem is that, the items $rep_titles on the 2nd content goes back or loops back to the 1st item where the item should start on the 3rd item. I have no problem with the images because it starts where I want it to be. Is there a way to get around this?
According to the array_slice doc you unintentionally have reset the array index to zero. You need an extra fourth parameter (a boolean) to indicate you don't want that reset to take place, like this:
#foreach (array_slice($images, 3, 3, true) as $keyIndex => $image) {
// rest of your code
}
From http://php.net/manual/en/function.array-slice.php:
preserve_keys
Note that array_slice() will reorder and reset the integer array indices by default. You can change this behaviour by setting preserve_keys to TRUE. String keys are always preserved, regardless of this parameter.

How to search strings inside Array of arrays using eloquent

So I have a databse column where the content is an Array like this:
[{"tag_name":"example1"},{"tag_name":"example2"}, {"tag_name":"example3"}]
What I am trying to do is to retrieve videos with a certain tag. All the videopages have specific tags, and when a user clicks one of those tags, it is redirected to a view where similar videos with the same tag will be displayed.
Right now I have the following controller:
public function search($tag){
$tag = urldecode($tag);
$videos = Video::where('tags', 'LIKE', $tag)->paginate(12);
$settings = Detail::find(1);
$ads = Ad::find(1);
return view('search', ['videos' => $videos, 'settings' => $settings, 'ads' => $ads]);
}
And I have the following view (search.blade.php):
#foreach($videos as $video)
<div class="col-lg-4 col-xs-12">
<div class="row justify-content-center">
<img class="articleImg" src="{{$video->imgurl}}">
</div>
<div>
<p class="float-left">{{$title = substr($video->title, 0, 30) . " ..."}}</p>
<small class="duration float-right">{{$video->duration}}</small>
<div class="progress float-right">
<div class="progress-bar bg-success" role="progressbar" style="width: {{$video->rating}}%" aria-valuenow="{{$video->rating}}" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</div>
#endforeach
The problem is that right now, no videos are shown in my view, even tough i get no errors at all. Is it because the columns has an array of arrays?
I assume it's because your controller is returning 0 videos because tag never match.
You are using LIKE statement without escaping your tag variables with %, so you are looking to match something that is exactly like tag, and because you have an array of tags as a column that will never happen.
One solution you could implement is changing your tag to something like this:
public function search($tag){
$tag = urldecode($tag);
$videos = Video::where('tags', 'LIKE', '%'.$tag.'%')->paginate(12);
$settings = Detail::find(1);
$ads = Ad::find(1);
return view('search', ['videos' => $videos, 'settings' => $settings, 'ads' => $ads]);
}
Here you can read more about the LIKE operator :D

Protractor: Finding the right element to test

I think I'm misunderstanding how elements works..
HTML code:
<div id="div-item">
A link
<form>
<div>
<select>
<option>1</option>
<option>2</option>
</select>
</div>
</form>
</div>
When I do this:
element(by.tagName('select')).all(by.tagName('option')).count();
This gives me 2, which is correct
When I do this:
element(by.id('div-item')).element(by.tagName('select')).all(by.tagName('option')).count();
This gives me 0. I thought chaining elements finds sub-elements. Is this not correct? How do I restrict the .all(by.tagName('option')) only within this div, rather than the whole page?
This is the xeditable library. My HTML code is:
<div id="div-item" class="col-xs-3">
<a id="xeditable-link" href="#" ng-if="canEdit"
editable-select="user_id"
e-ng-options="user.id as user.name for user in users"
onbeforesave="updateProfile({user_id: $data})">
{{ showNameFromID(user_id) || 'none'}}
</a>
</div>
But this generates a lot of HTML code. It's something like:
<div id="div-item" class="col-xs-3">
<a id="xeditable-link" href="#" ng-if="canEdit"
editable-select="user_id"
e-ng-options="user.id as user.name for user in users"
onbeforesave="updateProfile({user_id: $data})">
{{ showNameFromID(user_id) || 'none'}}
</a>
<form ...>
<div class="xeditable-controle..." ...blah blah>
<select ...ng-options="..." blah blah>
<option>1</option>
<option>2</option>
</select>
<span> ...the buttons... </span>
</div>
</form>
</div>
My test spec:
it('should pass ...', function() {
element(by.id('xeditable-link')).click(); // Click the link to bring up xeditable
element(by.tagName('select')).click(); // Click the select to bring up the popup
var allOptions = element(by.id('div-item')).element(by.tagName('select')).all(by.tagName('option'));
expect(allOptions.count()).toBe(2);
for (var i = 0; i < 2; ++i) {
expect(allOptions.get(i).getText()).toBe(testText[i]);
}
});
Both of the expect statements fail. count is 0, instead of 2 and "NoSuchElementError: No element found using locator: By.tagName("select")"
Try a single css locator
$$('#div-item select [option]').count()
// The same as
element.all(by.css('#div-item select [option]')).count()
Turns out i had a 'div-item' in another .html file. Since AngularJS is a single page application, it was picking up that one instead of the one I wanted.

Why am I getting "Error: 'undefined' is not a function (evaluating 'items.split(',')')" here?

I'm getting the following error while typing into the field filtered by 'completeList'. Why is this happening?
JavaScript
angular.module('myApp', ['timer'])
.controller('AppCtrl',['$scope', function($scope){
$scope.gameOn = true;
$scope.leaders = true;
$scope.myScore = true;
}])
.filter('completeList', function() {
return function(items) {
var list = [];
if(items) {
list = items.split(',');
var last = list[list.length - 1];
if(items.charAt(items.length - 1) != ',' || last.length === 0)
list.pop();
}
return list;
};
});
HTML
<div ng-show="gameOn" ng-controller="LabelCtrl" class="row marketing">
<div class="col-lg-4">
<h4>Enter comma-separated labels for this image</h4>
<form role="form" class="form-inline" >
<input ng-list ng-model="labels" placeholder="Enter labels" class="form-control" type="text" >
<button class="form-control" class="btn btn-xs btn-success">Submit</button>
</form>
</div>
<div class="col-lg-2">
<h4>Labels</h4>
<div>
<ol>
<li ng-repeat="label in labels track by $index | completeList">
{{ label }}
</li>
</ol>
</div>
</div>
The good news is that you only have a minor Angular syntax error. It is actually mentioned in the documentation:
Filters should be applied to the expression, before specifying a
tracking expression.
...
For example: 'item in items | filter:searchText track by item.id' is a pattern that might be used to apply a filter to items in conjunction with a tracking expression.
Given this knowledge, just change your ngRepeat line to the following, it does work exactly as you intended and works perfectly on my side:
<li ng-repeat="label in labels | completeList track by $index">
I do not know what the data structure of labels so here is my best stab at it. Filters are applied onto the instance of your iteration of your loop. It looks like you may be trying to apply the filter to the entire collection instead of that index of the loop. The filter is applied to label not labels. In this case you cannot split it. Again I dont know your data structure so I am kind of guessing here. It would be helpful if you could reveal what labels is.
Thanks,
Jordan

Resources