Update user meta - array - arrays

I'm developing comments sections for my user profile and I'm giving an option to user to make comment visible or not.
I've created an array:
$comment = array($comment_name, $comment_text, $time, $visible);
Where $visible is false value at default.
And then I add_user_meta
add_user_meta($user->ID, 'recommend_comment', $comment);
This is working perfect for me, I've got an array of comments displayed.
Now I want to update array with $visible = true if user clicks on button but not sure how to access specific array row with update_user_meta.
I tried with:
update_user_meta($user->ID, 'recommend_comment', $prikazi, [2]);
But that's not working. Any idea how to make this?

You can use update_user_meta() for adding and/or updating, see reference: update_user_meta
To update visible you can do:
$comment = get_user_meta( $user->ID, 'recommend_comment', TRUE );
if( !empty( $comment ) ) {
$comment[3] = FALSE;
update_user_meta( $user->ID, 'recommend_comment', $comment );
}
To improve it a bit you could instead use keys in the array, for example:
$comment = array( 'name' => $comment_name, 'text' => $comment_text, 'time' => $time, 'visible' => $visible);
// And then you can access with:
$comment['visible'] = TRUE;
UPDATE: example with a list of comments:
$comments = array(
array( 'name' => 'AAA', 'text' => 'Just a comment', 'time' => '12:50', 'visible' => FALSE ),
array( 'name' => 'BBB', 'text' => 'Another one', 'time' => '14:10', 'visible' => TRUE ),
);
// Create/updates the comments
update_user_meta( $user->ID, 'recommend_comment', $comments );
// ...
// Load the comments
$comments = get_user_meta( $user->ID, 'recommend_comment', TRUE );
if( !empty( $comment ) ) {
// then you can manipulate them with:
$comments[1]['visible'] = FALSE;
// and update the meta as before
update_user_meta( $user->ID, 'recommend_comment', $comments );
}

This works for me.
//delete_user_meta(get_current_user_id(), 'watchlist');
$new_value = $_GET['id'];
if(empty($new_value)){
echo 'No value';
die();
}
$watchlist = get_user_meta( get_current_user_id(), 'watchlist', true);
if( !empty( $watchlist ) ) {
$check_value = unserialize( $watchlist );
// Check if value exists
if( in_array( $new_value, $check_value ) ){
echo 'Already exists';
}else{
$check_value[] = $new_value;
update_user_meta( get_current_user_id(), 'watchlist', serialize( $check_value ) );
}
}else{
update_user_meta( get_current_user_id(), 'watchlist', serialize( [$new_value] ));
}
print_r(unserialize( $watchlist ));

Related

How can I get an array of custom categories in Wordpress?

I have registered a custom taxonomy as part of my custom post type, but when passing it through to get_categories() it returns an empty array. Any ideas as to why?
// Register FAQ Categories taxonomy
function bv_faq_register_categories() {
register_taxonomy(
'faq-category',
'faq',
array(
'label' => 'Categories',
'rewrite' => array('slug' => 'faq-category'),
'hierarchical' => true
)
);
}
add_action('init', 'bv_faq_register_categories');
// Category view
$categories = get_categories(array(
'taxonomy' => 'faq-category'
));
$categories is returning an empty array.
Have you tried get_terms instead?
$categories = get_terms( 'faq-category', array(
'orderby' => 'count',
'hide_empty' => 0
) );
Like #AD Styles said I would use get_terms using the custom taxonomy, to expand a bit here's some example code:
<?php
$post_type = 'faq-category';
// Get all the taxonomies for this post type
$taxonomies = get_object_taxonomies( (object) array( 'post_type' => $post_type ) );
foreach( $taxonomies as $taxonomy ) :
// Gets every "category" (term) in this taxonomy to get the respective posts
$terms = get_terms( array(
'taxonomy' => $taxonomy,
'parent' => 0
) );
foreach( $terms as $term ) :
echo "<h1>".$term->name."</h1>";
endforeach;
endforeach;
?>
Your code looks ok. Do you have assigned this category to any post/post type?
If not then you will get an empty result. for testing you can set 'hide_empty' = false like this:
// Category view
$categories = get_categories(array(
'taxonomy' => 'faq-category',
'hide_empty' => false // set it true
));
Also, you can use get_terms() function.

Random hidden value in Drupal form

I am developing simple guestbook module for one of my customers and as a spam prevention I decided to use an array of simple questions. For this I have to pick random question from the array and set the ID of this question (array element ID) in form so I can check the answer in submit handler. The problem is that the form is regenerated before the submit handler is evaluated so the random value changes.
Shortly: I am getting other value of $form_state['values']['queston_id'] in submit handler function that it is in form. Why is that and how can I change this?
Thanks a lot!
This is my module:
function gb_menu() {
$items = array();
$items['gb'] = array(
'title' => t('Guestbook'),
'description' => t('Guestbook page'),
'page callback' => 'gb_guestbook',
//'page arguments' => array('gb_guestbook'),
'access arguments' => array('view guestbook'),
);
return $items;
}
function gb_guestbook() {
dpm('generating page');
$page = NULL;
$page .= drupal_render(drupal_get_form('gb_guestbook_form'));
$page .= 'list of guestbook messages here';
return $page;
}
function gb_guestbook_form($form, &$form_state) {
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#description' => t('Please, enter your name.'),
);
$form['message'] = array(
'#type' => 'textarea',
'#cols' => 5,
'#title' => t('Message'),
'#description' => t('Please, enter your message.'),
);
$questions = gb_get_question();
$question_id = rand(0, count($questions)-1);
$question = $questions[$question_id];
$form['question_id'] = array(
'#type' => 'hidden',
'#value' => $question_id,
);
$form['spam'] = array(
'#title' => $question['question'],
'#description' => t('Please, answer the simple question so we know that you are a human.'),
'#type' => 'textfield',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
}
function gb_guestbook_form_submit($form, &$form_state) {
// spam check
$values = $form_state['values'];
$questions = gb_get_question();
$answers = $questions[$values['question_id']]['answers'];
if (!in_array(strtolower($values['spam']), $answers)) {
drupal_set_message(t('You did not reply the answer correctly. Are you sure it was not typo?'), 'error');
}
else {
drupal_set_message(t('Thanks for the contribution!'), 'status');
// processing input
}
}
function gb_get_question() {
return array(
array (
'question' => t('What is the capital of Slovakia?'),
'answers' => array('bratislava'),
),
array (
'question' => t('What is the name of this band?'),
'answers'=> array('divozel'),
),
array (
'question' => t('What is the biggest town in east part of Slovakia?'),
'answers' => array('košice','kosice'),
),
);
}
You should probably do this check in gb_guestbook_form_VALIDATE instead.
I'd do this in a validation hook. Also another issue in the function gb_guestbook_form_submit
You get the questions but not the answers array and then you are trying to compare them. This could also be the source of your issue, you capture questions but not answers and then compare to the empty array of answers.
Wrap your random question generator in a conditional statement that checks if your question has been defined in the form yet.
$question_id = NULL;
$questions = gb_get_question();
if (!isset($form['question_id'])) {
$question_id = rand(0, count($questions)-1);
}
else {
$question_id = $form['question_id']['#value'];
}
$question = $questions[$question_id];
Not sure why my other answer isn't working for you, but here's another approach. The idea would be to store the question id in $form_state['storage'].
First, correct your form declaration so it passes in $form_state as a reference.
function gb_guestbook_form($form, &$form_state) {
Now check the $form_state['storage'] array for your question id, and set it if you haven't already, before you set the form value question_id.
$questions = gb_get_question();
if (!isset($form_state['storage']['question_id'])) {
$form_state['storage']['question_id'] = array_rand($questions);
}
$form['question_id'] = array(
'#type' => 'hidden',
'#value' => $form_state['storage']['question_id'],
);
Your problem (and mine) is describe here:
http://www.sparklepod.com/myblog/drupal-form-same-form-for-build-and-validation/
In short. On submit the form is rebuild before the validation code is run. For me the solutions in the blog is not working for my Drupal 7 site.
What I have done is added the following line to the forum build:
$form_state['cache'] = true;
That will cache the form and the on _submit I will set it to false.

cakephp cakedc between

I'd like to use the 'between' example from cakedc, but just can't make sense out of it.
'range' => array('type' => 'expression', 'method' => 'makeRangeCondition', 'field' => 'Article.views BETWEEN ? AND ?'),
I have field qca_start in my table and want user to provide two values (from, to) and search for qca_start between from and to.
My controller:
(I've used other simpler searches without problem. (employee_id works just fine here)
public $presetVars = array(
array('field' => 'employee_id', 'type' => 'value'),
array('field' => 'qca_start', 'type' => 'value') // not sure what type to use here for between search.
};
The field on my table is qca_start, not user how would i name the presetVar for this?
On my model
public $filterArgs = array(
array('name' => 'employee_id', 'type' => 'value'),
'range' => array('type' => 'expression', 'method' => 'makeRangeCondition', 'field' => 'Article.views BETWEEN ? AND ?'),
);
I don't know how to format this for filterArgs:
'range' => array('type' => 'expression', 'method' => 'makeRangeCondition', 'field' => 'Article.views BETWEEN ? AND ?'),
I want qca_start to be between search values One and Two.
Can you help?
a copy/paste from the answer i gave # CakeDC Plugin Search Between Dates
in model :
'creationDateBetween' => array(
'type' => 'expression',
'method' => 'CreationDateRangeCondition',
'field' => 'MODEL.creationdate BETWEEN ? AND ?',
),
public function CreationDateRangeCondition($data = array()){
if(strpos($data['creationDateBetween'], ' - ') !== false){
$tmp = explode(' - ', $data['creationDateBetween']);
$tmp[0] = $tmp[0]."-01-01";
$tmp[1] = $tmp[1]."-12-31";
return $tmp;
}else{
return array($data['creationDateBetween']."-01-01", $data['creationDateBetween']."-12-31");
}
}
in view : note that i'm using a slider for year range
echo $this->Form->input('creationDateBetween',
array(
'label' => __('Creation date between X and Y'),
'div' => false,
'style' => 'border: 0; color: #49AFCD; font-weight: bold;'
)
);
?><div id="creationDateBetweenSlider" style="padding:0;"></div><?php
<script>
$(function() {
var creationDateBetweenSlider = $( "#creationDateBetweenSlider" ),
institutionCreationDateBetween = $( "#MODELCreationDateBetween" ),
lock = 0;
creationDateBetweenSlider.slider({
range: true,
min: 1900,
max: 2050,
values: [ 2000, 2013 ],
slide: function( event, ui ) {
MODELCreationDateBetween.val( ui.values[ 0 ] + " - " + ui.values[ 1 ] );
}
});
if(lock != 0) MODELCreationDateBetween.val( creationDateBetweenSlider.slider( "values", 0 ) + " - " + creationDateBetweenSlider.slider( "values", 1 ) );
lock = 1;
});
</script>
waiting for feedback to see if it works for you ;)
You should read the documenation # https://github.com/cakedc/search
'expression' type useful if you want to add condition that will
generate by some method, and condition field contain several parameter
like in previous sample used for 'range'. Field here contains
'Article.views BETWEEN ? AND ?' and Article::makeRangeCondition
returns array of two values.
So just return 2 values in your method:
public function makeRangeCondition() {
...
return array($from, $to);
}
They will automatically replace the two ? in this order then.

Custom Field with autcomplete

I am trying to build my own node reference custom field - I know several projects out there already do this, I am building this in order to learn... :)
My problem is the autocomplete path, it's not being triggered, I have checked the noderefcreate project and implemented my solution based on that project. But still; nothing is being triggered when I check firebug.
Here is my code:
function nodereference_field_widget_info() {
return array(
'nodereference_nodereference_form' => array(
'label' => t('Node Reference Form'),
'field types' => array('nodereference'),
'behaviors' => array(
'multiple values' => FIELD_BEHAVIOR_DEFAULT,
'default value' => FIELD_BEHAVIOR_DEFAULT,
),
'settings' => array(
'autocomplete_match' => 'contains',
'autocomplete_path' => 'nodereference/autocomplete',
),
),
);
}
function nodereference_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
if ($instance['widget']['type'] == 'nodereference_nodereference_form') {
$widget = $instance['widget'];
$settings = $widget['settings'];
$element += array(
'#type' => 'textfield',
'#default_value' => isset($items[$delta]['nid']) ? $items[$delta]['nid'] : NULL,
'#autocomplete_path' => $instance['widget']['settings']['autocomplete_path'],
);
}
return array('nid' => $element);
}
You need to define method from where auto compete will take suggestions.
It can be done like this:
/**
* implements hook_menu
*/
function your_module_name_menu() {
$items['master_place/autocomplete'] = array(
'page callback' => '_your_module_name_autocomplete',
'access arguments' => array('access example autocomplete'),
'type' => MENU_CALLBACK
);
return $items;
}
/**
* Auto complete method implementation
* #param $string
*/
function _your_module_name_autocomplete($string) {
$matches = array();
// Some fantasy DB table which holds cities
$query = db_select('target_db_table', 'c');
// Select rows that match the string
$return = $query
->fields('c', array('target_column'))
->condition('c.target_column', '%' . db_like($string) . '%', 'LIKE')
->range(0, 10)
->execute();
// add matches to $matches
foreach ($return as $row) {
$matches[$row->city] = check_plain($row->city);
}
// return for JS
drupal_json_output($matches);
}

Populating #options, #header for tableselect in ajax callback function

What I am trying to do is display a table with checkboxes on the press of a button by ajax. The table should be initially hidden and get populated on the fly by a function call.
If initially I load $options1 with some dummy values , then after ajax call it throws in an error saying-
Notice: Undefined index: red in theme_tableselect() (line 3285 of
D:\wamp\www\drupal7\includes\form.inc).
where 'red' is the index of a dummy row value and #options don't get populated with the new values. What is the way to get this working ?
Here is the code for the form-
$form['mltag_new']['tag'] = array(
'#type' => 'button',
'#value' => t("Suggest Tags"),
'#ajax' => array(
'callback' => 'mltag_suggest_tags_ajax',
'wrapper' => 'mltag_suggest_tags_table_div',
'effect' => 'slide',
),
);
$options1 = array(); //initial dummy values
$options1['red']['tag'] = "A red row";
$options1['red']['chi'] = "A red row";
$form['mltag_new']['myselector'] = array (
'#type' => 'tableselect',
'#title' => 'My Selector',
'#header' => $header,
'#options' => $options1,
'#prefix' => '<div id="mltag_suggest_tags_table_div">',
'#suffix' => '</div>',
);
return $form;
and the Ajax callback looks something like this-
function mltag_suggest_tags_ajax($form, $form_state) {
//$content has some content
//pass the content to a function
include_once 'includes/content_tag.inc';
$tags = mltag_content_tag($content, variable_get('algo_type'), 20);
if (empty($tags)) {
$output .= t('Content is insufficient to generate Tags using this algorithm. <br>Please choose other algorithm from Settings Page.');
$form['mltag_new']['sample_text']['#markup'] = $output;
return $form['mltag_new']['sample_text'];
}
else {
$algo = variable_get('algo_type');
if ($algo == 1) {
$header = array(
'tag' => t('Tag'),
'frequency' => t('Frequency'),
);
$options = array();
foreach ($tags as $key => $value) {
$options[$key] = array(
'tag' => $key,
'frequency' => $value,
);
}
}
elseif ($algo == 2) {
$header = array(
'tag' => t('Tag'),
'chi' => t('Chi Square Value'),
);
$options = array();
foreach ($tags as $key => $value) {
$options[$key] = array(
'tag' => $key,
'chi' => $value,
);
}
}
$form['mltag_new']['myselector']['#header'] = $header;
$form['mltag_new']['myselector']['#options'] = $options;
return $form['mltag_new']['myselector'];
}
}
I replied to your post on Drupal.org about how I'm working on a somewhat similar problem. Try adding
$form['mltag_new']['myselector'] =
form_process_tableselect($form['mltag_new']['myselector']);
just before your return. Hopefully that helps you more than it did me. Beware that the #options just get rendered when the block reloads from the ajax, but the original $form object doesn't seem to be aware.
I know that this is a few years later, but I found this while searching for my own solution:
The tableselect module creates checkboxes in the $ form that have to be removed. in the example above, they would be in $form['mltag_new']['myselector'] with keys equal to the original $option1 in your original code. If you unset those, then call
$form['mltag_new']['myselector'] = form_process_tableselect($form['mltag_new']['myselector']);
before your return, it will eliminate the dummy rows.

Resources