Silverstripe 4 silvershop optionsetfield customise with two values and date expiration if poss - silverstripe

My client wants to have a location and date on the attributes for SilverShop which is fine. I have done this to allow the two fields to work back end. But trying to combine two values into a dropdown or optionset. PHP is not my strong point and probably is very simple.
so below is the code required to change. So the $location and $thedate are the values that need to be put together ie. London - 24/04/2020.
So at the moment it is working with just location and I cannot workout how to put them together with hyphen in the middle.
public function getOptionsetField($emptystring = null, $values = null)
{
$values = ($values) ? $values : $this->Values()->sort(['Sort' => 'ASC', 'Value' => 'ASC']);
$location = 'Location';
$thedate = 'TheDate';
if ($values->exists()) {
$field = OptionsetField::create(
'ProductAttributes[' . $this->ID . ']',
$this->Name,
$values->map('ID', $location )
);
return $field;
}
return null;
}
Another function I wanted to incorporate was that of not showing the values with dates gone past. So hide past dates. ie expiration.
This was the old site code and was wondering if I could incorporate in this code by any chance.
public function hasExpired() {
return (strtotime($this->TheDate) > time());
}
Thanks

Related

How set value of existing product attribute in Wordpress?

My every product in WooCommerce has several attributes. One of them is named my-availability and I need to change its value dynamically depending on stock change and some condition logic. So when the amount of pieces on stock is changed (usually decreased by order), the value of my-availability attribute will change. It should not add any new attributes, just change the value of the existing one. I do not use product variations at all.
I am total beginner and trying to build this piece of code for few days using a lot of googling. Now I have something like this:
function changeatt( $order )
{
$items = $order->get_items();
foreach( $items as $item ) {
$value2 = get_field( "naceste", $item['product_id']); //need to get value of custom field "naceste"
$value = get_post_meta( $item['product_id'], '_stock', true ); //need to get how many pcs is on stock
if ($value == 0 && $value2 > 0)
{$avl = 'Coming soon';}
if ($value == 0 && $value2 == 0)
{ $avl = 'Not in stock';}
if ($value > 0)
{ $avl = 'In stock';}
// update_post_meta( $item['product_id'], 'my-availability', $avl );
wp_set_object_terms( $item['product_id'], $avl, 'pa_my-availability', false);
}
}
add_action( 'woocommerce_reduce_order_stock', changeatt );
This code actually creates new custom field my-availability with the correct value, but I need to save it to existing attribute named my-availability instead. What am I missing?
I found it! update_post_meta did not work for changing attributes, do not know why. wp_set_object_terms must be used instead and pa_ must be added to the name of the attribute. I have edited the code in the question to the working version. The previous not-working line has been removed by // for other beginners, who will be solving the same situation to learn from this one. It took me few days to solve this.
Now I am pretty curious, how to find out, which types of variables can be changed using update_post_meta and which types using wp_set_object_terms.

How can I get the format the results of a CheckboxsetField as a comma separated string in SilverStripe?

I'm trying to create some filters for a datalist. I'd like the user to be able to select one or multiple filters from a list of tags and then spit out a list of objects based on those filters. All is good using this code to grab data based on the URL params being sent...
public function index(SS_HTTPRequest $request)
{
// ...
if($tagsParam = $request->getVar('tags')) {
$articles = new ArrayList();
$tagids = explode(",", $tagsParam);
foreach($tagids AS $tagid) {
$tag = Category::get()->byID($tagid);
$articleitems = $tag->getManyManyComponents('Articles')->sort('Date DESC');
foreach($articleitems AS $articleitem) {
$articles->push($articleitem);
}
}
}
$data = array (
'Articles' => $articles
);
if($request->isAjax()) {
return $this->customise($data)->renderWith('ListItems');
}
return $data;
}
That code works fine with a URL like mysite.com/?tags=1,2,3
My issue comes with trying to generate that URL based on the filters built with a CheckboxSetField. Here is my code for that...
public function ArticlesSearchForm()
{
$tagsmap = $this->getTags()->map('ID', 'Title')->toArray();
$form = Form::create(
$this,
'ArticlesSearchForm',
FieldList::create(
CheckboxSetField::create('tags')
->setSource($tagsmap)
),
FieldList::create(
FormAction::create('doArticlesSearch','Search')
)
);
$form->setFormMethod('GET')
->setFormAction($this->Link())
->disableSecurityToken()
->loadDataFrom($this->request->getVars());
return $form;
}
When the user submits that form, the URL generated is something along the lines of mysite.com?tags%5B1%5D=1&tags%5B2%5D=2&action_doArticlesSearch=Search Obviously, it's passing the values as an array. How can I pass a simple comma separated list?
Rather than trying to change the return of CheckboxSetField, I'd recommend changing your code. Given you are converting the comma-separated list list into an array already here:
$tagids = explode(",", $tagsParam);
Something like this, will skip this step:
public function index(SS_HTTPRequest $request)
{
// ...
if($tagsParam = $request->getVar('tags')) {
$articles = new ArrayList();
//This has a minor risk of going bad if $tagsParam is neither an
//array of a comma-separated list
$tagids = is_array($tags) ? $tagsParam : explode(",", $tagsParam);

Filter ModelAdmin by many_many relation

I'm managing the DataObject class 'trainer' with ModelAdmin. A trainer has a many_many relation to my other class 'language'.
On my 'trainer' class I'm manipulating the 'searchableFields' function to display a ListboxField in the filters area.
public function searchableFields() {
$languagesField = ListboxField::create(
'Languages',
'Sprachen',
Language::get()->map()->toArray()
)->setMultiple(true);
return array (
'Languages' => array (
'filter' => 'ExactMatchFilter',
'title' => 'Sprachen',
'field' => $languagesField
)
);
}
That works like expected and shows me the wanted ListboxField. The Problem is, after selecting 1 or 2 or whatever languages and submitting the form, I'm receiving
[Warning] trim() expects parameter 1 to be string, array given
Is it possible here to filter with an many_many relation? And if so, how? Would be great if someone could point me in the right direction.
Update:
Full Error Message: http://www.sspaste.com/paste/show/56589337eea35
Trainer Class: http://www.sspaste.com/paste/show/56589441428d0
You need to define that logic within a $searchable_fields parameter instead of the searchableFields() which actually constructs the searchable fields and logic.
PHP would be likely to throw an error if you go doing fancy form stuff within the array itself, so farm that form field off to a separate method in the same DataObject and simply call upon it.
See my example, I hope it helps.
/* Define this DataObjects searchable Fields */
private static $searchable_fields = array(
'Languages' => array (
'filter' => 'ExactMatchFilter',
'title' => 'Sprachen',
'field' => self::languagesField()
)
);
/* Return the searchable field for Languages */
public function languagesField() {
return ListboxField::create(
'Languages',
'Sprachen',
Language::get()->map()->toArray()
)->setMultiple(true);
}
Yes, it's possible. You just need to override two methods - one in Trainer data object and one in TrainerModelAdmin. First one will make a field, second one will do filtering.
Trainer Data Object:
public function scaffoldSearchFields($_params = null)
{
$fields = parent::scaffoldSearchFields($_params);
// get values from query, if set
$query = Controller::curr()->request->getVar('q');
$value = !empty($query['Languages']) && !empty($query['Languages']) ? $query['Languages'] : array();
// create a field with options and values
$lang = ListboxField::create("Languages", "Sprachen", Language::get()->map()->toArray(), $value, null, true);
// push it to field list
$fields->push($lang);
return $fields;
}
Trainer Model Admin
public function getList()
{
$list = parent::getList();
// check if managed model is right and is query set
$query = $this->request->getVar('q');
if ($this->modelClass === "Trainer" && !empty($query['Languages']) && !empty($query['Languages']))
{
// cast all values to integer, just to be sure
$ids = array();
foreach ($query['Languages'] as $lang)
{
$ids[] = (int)$lang;
}
// make a condition for query
$langs = join(",", $ids);
// run the query and take only trainer IDs
$trainers = DB::query("SELECT * FROM Trainer_Languages WHERE LanguageID IN ({$langs})")->column("TrainerID");
// filter query on those IDs and return it
return $list->filter("ID", $trainers);
}
return $list;
}

custom tax term; set post term issue

I am trying to set the post custom taxonomy via two variables (parent Id and child Id) that I've gotten from another function in my plugin file. var's $a and $b
When I manually enter the term ID - everything works fine but when I try to use a variable - to set the term id - it doesn't work
The function for getting the id's in the first code snippet, and trying to save the terms in the second snippet.
//***IF YOU HAVE MODEL GET THE ID
if(!empty($auto_model)){
$auto_model_id = get_term_by( 'slug', $auto_model, $this->tax );
$auto_model_id = $auto_model_id->term_id;
} // end get model id
if ($auto_make_id !== null && $auto_model_id !== null) { // +++++ IF YOU HAVE BOTH
$this->p_id = $auto_make_id; // define variable
$this->c_id = $auto_model_id; // define variable
// set post with both these terms - jump to set post and pass ids to set post
//return $p_id;
return $c_id . $p_id;
}
function cicb_do_things($post_id) { // use this as the final build up before sending to construct
global $auto_make,$auto_model;
$this->makemodel();
$a = $this->p_id;
$b = $this->c_id;
$tag = array( 45 ); // this is how wp wants me to do it; and when I do the wp_set object works great
var_dump ($tag);
echo '<br>';
$tag = array( $a ); // when I put in my variable which is the also 45 - the term does not work
wp_set_object_terms( $post_id, $tag, $this->tax );
}

Get gravity forms fields

I am using the gravity form on my site. I am working on create the custom report for this I have need gravity form fields name and id based on specific form id.Please let me know how I can do it.
I am using the following function but it is showing all forms info based on it. it is looking very hard to parse it. Please let me know any function so I can get fields name easily.
$forms = RGFormsModel::get_forms_by_id(13);
try this
function get_all_form_fields($form_id){
$form = RGFormsModel::get_form_meta($form_id);
$fields = array();
if(is_array($form["fields"])){
foreach($form["fields"] as $field){
if(isset($field["inputs"]) && is_array($field["inputs"])){
foreach($field["inputs"] as $input)
$fields[] = array($input["id"], GFCommon::get_label($field, $input["id"]));
}
else if(!rgar($field, 'displayOnly')){
$fields[] = array($field["id"], GFCommon::get_label($field));
}
}
}
//echo "<pre>";
//print_r($fields);
//echo "</pre>";
return $fields;
}
It's not that hard to parse:
$fields=array();
foreach ( $forms['fields'] as $field ) {
$fields[]=array($field['id'] => $field['inputName']);
}
P.S. I'm assuming you use Gravity Forms < 1.7 as RGFormsModel::get_forms_by_id is a deprecated function since 1.7
// Get the Form fields
$form = RGFormsModel::get_form_meta($form_id);
// Run through the fields to grab an object of the desired field
$field = RGFormsModel::get_field( $form, $field_id );
I use the above to get a specific field I want to filter the value of. The $field contains an object with all the properties you want.
echo $field->label // Gets the label
echo $field->inputName // Gets the name
echo $field->type // Gets the type
echo $field->cssClass // Gets the CSS Classes as a string
You are able to get the entered value/content of a field by using rgpost() and by referencing the id ($field->id).
// Check the entered value of every field
foreach( $form['fields'] as &$field ) {
// Get the content for the specific field
$fieldContent = rgpost( "input_".$field->id );
// Check the content
if ( $fieldContent == ... ){}
}

Resources