Is there a clean way to remove the draggable option on multiple-value CCK fields? I assume I could style it out with CSS but that doesn't seem like the "right" way to do it.
Ideally, the draggable option wouldn't be available for any users except admins.
It looks like the tabledrag stuff is being built in the cck theme functions - eg theme_content_multiple_values it's adding a 'draggable' class to the table rows, and calling
drupal_add_tabledrag on the table.
You should be able to override this in your theme/module(?) and add a fairly simple switch to test for users with an appropriate permission before adding the drag.
Thanks for the tip #Andrew. Here's what I ended up coming up with:
function stannes_content_multiple_values($element) {
global $user;
$field_name = $element['#field_name'];
$field = content_fields($field_name);
$output = '';
if ($field['multiple'] >= 1) {
$table_id = $element['#field_name'] .'_values';
$order_class = $element['#field_name'] .'-delta-order';
$required = !empty($element['#required']) ? '<span class="form-required" title="'. t('This field is required.') .'">*</span>' : '';
$header = array(
array( 'data' => t('!title: !required', array('!title' => $element['#title'], '!required' => $required)), 'colspan' => 2)
);
if ($user->uid == 1) {
$header[] = t('Order');
}
$rows = array();
// Sort items according to '_weight' (needed when the form comes back after
// preview or failed validation)
$items = array();
foreach (element_children($element) as $key) {
if ($key !== $element['#field_name'] .'_add_more') {
$items[] = &$element[$key];
}
}
usort($items, '_content_sort_items_value_helper');
// Add the items as table rows.
foreach ($items as $key => $item) {
$item['_weight']['#attributes']['class'] = $order_class;
$delta_element = drupal_render($item['_weight']);
if ($user->uid == 1) {
$cells = array(
array('data' => '', 'class' => 'content-multiple-drag'),
drupal_render($item),
array('data' => $delta_element, 'class' => 'delta-order'),
);
} else {
$cells = array(
drupal_render($item)
);
}
$rows[] = array(
'data' => $cells,
'class' => 'draggable',
);
}
$output .= theme('table', $header, $rows, array('id' => $table_id, 'class' => 'content-multiple-table'));
$output .= $element['#description'] ? '<div class="description">'. $element['#description'] .'</div>' : '';
$output .= drupal_render($element[$element['#field_name'] .'_add_more']);
if ($user->uid == 1) {
drupal_add_tabledrag($table_id, 'order', 'sibling', $order_class);
}
} else {
foreach (element_children($element) as $key) {
$output .= drupal_render($element[$key]);
}
}
return $output;
}
Related
I want to add a new attribute to an existing woocommerce product. I use this code
$pf = new WC_Product_Factory();
$product = $pf->get_product(76);
//Create the attribute object
$attribute = new WC_Product_Attribute();
$attribute->set_id( 0 );
//pa_color slug
$attribute->set_name( 'color' );
//Set terms slugs
$attribute->set_options( array(
'blue',
) );
$attribute->set_position( 0 );
//If enabled
$attribute->set_visible( 1 );
$product->set_attributes(array($attribute));
$id = $product->save();
this code working fine but I want to add attributes with terms, this code create custom product attribute.
I want to create attribute like this image
How can I create key-value attributes?
Try this code
function get_attribute_id_from_name($name)
{
global $wpdb;
$attribute_id = $wpdb->get_var("SELECT attribute_id
FROM {$wpdb->prefix}woocommerce_attribute_taxonomies
WHERE attribute_name LIKE '$name'");
return $attribute_id;
}
function save_product_attribute_from_name($name, $label = '', $set = true)
{
if (!function_exists('get_attribute_id_from_name')){
return;
}
global $wpdb;
$label = $label == '' ? ucfirst($name) : $label;
$attribute_id = get_attribute_id_from_name($name);
$taxonomy = wc_attribute_taxonomy_name($name); // The taxonomy slug
if (empty($attribute_id)) {
$attribute_id = NULL;
}
else {
$set = false;
}
//register existing taxonomy
if (isset($attribute_id) && !taxonomy_exists($taxonomy)) {
register_attribute($name);
}
$args = array(
'attribute_id' => $attribute_id,
'attribute_name' => $name,
'attribute_label' => $label,
'attribute_type' => 'select',
'attribute_orderby' => 'menu_order',
'attribute_public' => 0,
);
if (empty($attribute_id)) {
$wpdb->insert("{$wpdb->prefix}woocommerce_attribute_taxonomies", $args);
set_transient('wc_attribute_taxonomies', false);
}
if ($set) {
$attributes = wc_get_attribute_taxonomies();
$args['attribute_id'] = get_attribute_id_from_name($name);
$attributes[] = (object)$args;
//print_r($attributes);
set_transient('wc_attribute_taxonomies', $attributes);
} else {
return;
}
}
function register_attribute($name)
{
$taxonomy = wc_attribute_taxonomy_name($name); // The taxonomy slug
$attr_label = ucfirst($name); // attribute label name
$attr_name = (wc_sanitize_taxonomy_name($name)); // attribute slug
register_taxonomy(
$taxonomy,
'product',
array(
'label' => __($attr_label),
'rewrite' => array('slug' => $attr_name),
'hierarchical' => true,
)
);
}
function add_product_attribute($product_id, $data)
{
$_pf = new WC_Product_Factory();
$product = $_pf->get_product($product_id);
$product_attributes = array();
foreach ($data['_attributes'] as $key => $terms) {
$taxonomy = wc_attribute_taxonomy_name($key); // The taxonomy slug
$attr_label = ucfirst($key); // attribute label name
$attr_name = (wc_sanitize_taxonomy_name($key)); // attribute slug
// NEW Attributes: Register and save them
if (!taxonomy_exists($taxonomy))
save_product_attribute_from_name($attr_name, $attr_label);
$product_attributes[$taxonomy] = array(
'name' => $taxonomy,
'value' => '',
'position' => '',
'is_visible' => 1,
'is_variation' => 1,
'is_taxonomy' => 1
);
foreach ($terms as $value) {
$term_name = ucfirst($value);
$term_slug = sanitize_title($value);
// Check if the Term name exist and if not we create it.
if (!term_exists($value, $taxonomy))
wp_insert_term($term_name, $taxonomy, array('slug' => $term_slug)); // Create the term
// Set attribute values
wp_set_object_terms($product_id, $term_name, $taxonomy, true);
}
$product->set_attributes(array($attribute));
}
update_post_meta($product_id, '_product_attributes', $product_attributes);
}
Then call function
add_product_attribute(76, [
'attributes' => [
'Attribute 1' => ['Value 1', 'Value 2'],
'Attribute 2' => ['Value 4', 'Value 5'],
],
]
);
I am trying to update my repeater field from front end-with files. In case with one field file - it works. But when I'm trying to fill repeater with files it doesn't work.
// JS. Ajaxly sending files
var ajaxurl = '<?php echo site_url() ?>/wp-admin/admin-ajax.php';
$('.js-new-msg-send').click(function (e) {
e.preventDefault();
var form = document.forms.namedItem("new_theme");
var formData = new FormData(form);
formData.append('user_id', '<?php echo $userID; ?>');
formData.append('action', 'msg_to_acf');
var xhr = new XMLHttpRequest();
xhr.open('POST', ajaxurl, true);
xhr.send(formData);
})
I found function to handle files uploading to acf field and modified it to handle multiple files from $_FILES variable:
// FOR MULTIPLE FILES
if ( !empty($_FILES[$f]['name']) && is_array($_FILES[$f]['name']) ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/image.php' );
$file_list = array();
foreach ($_FILES[$f]['name'] as $key => $value) {
$temp_file = array(
'name' => $_FILES[$f]['name'][$key],
'type' => $_FILES[$f]['type'][$key],
'tmp_name' => $_FILES[$f]['tmp_name'][$key],
'error' => $_FILES[$f]['error'][$key],
'size' => $_FILES[$f]['size'][$key]
);
wp_update_attachment_metadata( $pid, $temp_file );
$file = wp_handle_upload( $temp_file , array('test_form' => FALSE, 'action' => 'editpost') );
if ( isset( $file['error'] )) {
return new WP_Error( 'upload_error', $file['error'] );
}
$file_type = wp_check_filetype($temp_file['name'], array(
'jpg|jpeg' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
));
if ($file_type['type']) {
$name_parts = pathinfo( $file['file'] );
$name = $file['filename'];
$type = $file['type'];
$title = $t ? $t : $name;
$content = $c;
$attachment = array(
'post_title' => $title,
'post_type' => 'attachment',
'post_content' => $content,
'post_parent' => $pid,
'post_mime_type' => $type,
'guid' => $file['url'],
);
foreach( get_intermediate_image_sizes() as $s ) {
$sizes[$s] = array( 'width' => '', 'height' => '', 'crop' => true );
$sizes[$s]['width'] = get_option( "{$s}_size_w" ); // For default sizes set in options
$sizes[$s]['height'] = get_option( "{$s}_size_h" ); // For default sizes set in options
$sizes[$s]['crop'] = get_option( "{$s}_crop" ); // For default sizes set in options
}
$sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes );
foreach( $sizes as $size => $size_data ) {
$resized = image_make_intermediate_size( $file['file'], $size_data['width'], $size_data['height'], $size_data['crop'] );
if ( $resized )
$metadata['sizes'][$size] = $resized;
}
$attach_id = wp_insert_attachment( $attachment, $file['file'] /*, $pid - for post_thumbnails*/);
if ( !is_wp_error( $id )) {
$attach_meta = wp_generate_attachment_metadata( $attach_id, $file['file'] );
wp_update_attachment_metadata( $attach_id, $attach_meta );
}
$final_temp_arr = array(
'pid' =>$pid,
'url' =>$file['url'],
'file'=>$file,
'attach_id'=>$attach_id
);
array_push($file_list, $final_temp_arr);
}
}
return $file_list;
}
In final, I using this function to get an array of information with attach-id variable that I inserting to repeater.
$att = my_update_attachment( 'msg-file-list' , $post_id );
$files_final_list = array();
foreach ($att as $key => $val) {
array_push($files_final_list, $val['attach_id']);
}
$value_arr = array(
array(
"msg-author" => $user_name,
"msg-date" => $date,
"msg-read-check" => true,
"msg-cont" => $msg_cont,
'msg-file-list' => $files_final_list
)
);
update_field( 'test_file_list' , $files_final_list , $post_id );
I guess that mistake is in last part , where I trying to upload files to repeater. Can someone show me what I'am doing wrong? Thanks for helping.
I am trying to modify a plugin. I need the author id of the current post to accomplish what I am doing. I have tried every other method I have found over internet that claims to get the post author id outside the loop but its not working inside the plugin. I guess its because the plugins might be loaded before the loop variables or something? Please pardon me as I am not a Pro.
Here is what I have tried so far.
1.
$author_id=$post->post_author;
2.
global $post;
$author_id=$post->post_author;
3.
$post_tmp = get_post($post_id);
$author_id = $post_tmp->post_author;
4.
$author_id = $posts[0]->post_author;
But nothing works in the plugin's directory. Can anyone help?
Detailed Explanation:
I am trying to modify woodiscuz plugin. The problem with this plugin is that it held comments of even seller for moderation. So if I am the seller and I reply to some buyer in comment, I will have to approve my own comment.
Now to overcome this problem, I am putting a condition that if the author of the post (seller) is commenting, then don't put the comment for moderation.
Here is the function of the plugin that is controlling comments.
public function comment_submit_via_ajax() {
$message_array = array();
$comment_post_ID = intval(filter_input(INPUT_POST, 'comment_post_ID'));
$comment_parent = intval(filter_input(INPUT_POST, 'comment_parent'));
if (!$this->wpc_options->wpc_options_serialized->wpc_captcha_show_hide) {
if (!is_user_logged_in()) {
$sess_captcha = $_SESSION['wpc_captcha'][$comment_post_ID . '-' . $comment_parent];
$captcha = filter_input(INPUT_POST, 'captcha');
if (md5(strtolower($captcha)) !== $sess_captcha) {
$message_array['code'] = -1;
$message_array['message'] = $this->wpc_options->wpc_options_serialized->wpc_phrases['wpc_invalid_captcha'];
echo json_encode($message_array);
exit;
}
}
}
$comment = filter_input(INPUT_POST, 'comment');
if (is_user_logged_in()) {
$user_id = get_current_user_id();
$user = get_userdata($user_id);
$name = $user->display_name;
$email = $user->user_email;
$user_url = $user->user_url;
} else {
$name = filter_input(INPUT_POST, 'name');
$email = filter_input(INPUT_POST, 'email');
$user_id = 0;
$user_url = '';
}
$comment = wp_kses($comment, array(
'br' => array(),
'a' => array('href' => array(), 'title' => array()),
'i' => array(),
'b' => array(),
'u' => array(),
'strong' => array(),
'p' => array(),
'img' => array('src' => array(), 'width' => array(), 'height' => array(), 'alt' => array())
));
$comment = $this->wpc_helper->make_clickable($comment);
if ($name && filter_var($email, FILTER_VALIDATE_EMAIL) && $comment && filter_var($comment_post_ID)) {
$held_moderate = 1;
if ($this->wpc_options->wpc_options_serialized->wpc_held_comment_to_moderate) {
$held_moderate = 0;
}
// $held_moderate = 1 -> No moderation
/*This is the part where I need to put the custom condition*/
if($post_author_id == get_current_user_id())
{
$held_moderate = 1;
}
$new_commentdata = array(
'user_id' => $user_id,
'comment_post_ID' => $comment_post_ID,
'comment_parent' => $comment_parent,
'comment_author' => $name,
'comment_author_email' => $email,
'comment_content' => $comment,
'comment_author_url' => $user_url,
'comment_type' => 'woodiscuz',
'comment_approved' => $held_moderate
);
$new_comment_id = wp_insert_comment($new_commentdata);
$new_comment = new WPC_Comment(get_comment($new_comment_id, OBJECT));
if (!$held_moderate) {
$message_array['code'] = -2;
$message_array['message'] = $this->wpc_options->wpc_options_serialized->wpc_phrases['wpc_held_for_moderate'];
} else {
$message_array['code'] = 1;
$message_array['message'] = $this->comment_tpl_builder->get_comment_template($new_comment);
}
$message_array['wpc_new_comment_id'] = $new_comment_id;
} else {
$message_array['code'] = -1;
$message_array['wpc_new_comment_id'] = -1;
$message_array['message'] = $this->wpc_options->wpc_options_serialized->wpc_phrases['wpc_invalid_field'];
}
echo json_encode($message_array);
exit;
}
In Wordpress, I'm looking to get the depth a category's subcategories.
Suppose I have a category 'grandparent' which has a subcategory 'parent' which in turn has a subcategory 'child'. How do I get to integer 2?
I suppose I could check if 'grandparent' has subcategories and if it does, check if they have subcategories, etc, until I hit 0. But that seems like a lot of unnecessary processing.
Isn't there a more elegant way?
There is a nice blog post here that shows you how to build a function that will get you the depth of a category but not only... check the page the function has more options.
EDIT: code here:
function get_depth($id = '', $depth = '', $i = 0) {
global $wpdb;
if($depth == '') {
if(is_page()) {
if($id == '') {
global $post;
$id = $post->ID;
}
$depth = $wpdb->get_var("SELECT post_parent FROM $wpdb->posts WHERE ID = '".$id."'");
return get_depth($id, $depth, $i);
}
elseif(is_category()) {
if($id == '') {
global $cat;
$id = $cat;
}
$depth = $wpdb->get_var("SELECT parent FROM $wpdb->term_taxonomy WHERE term_id = '".$id."'");
return get_depth($id, $depth, $i);
}
elseif(is_single()) {
if($id == '') {
$category = get_the_category();
$id = $category[0]->cat_ID;
}
$depth = $wpdb->get_var("SELECT parent FROM $wpdb->term_taxonomy WHERE term_id = '".$id."'");
return get_depth($id, $depth, $i);
}
}
elseif($depth == '0') {
return $i;
}
elseif(is_single() || is_category()) {
$depth = $wpdb->get_var("SELECT parent FROM $wpdb->term_taxonomy WHERE term_id = '".$depth."'");
$i++;
return get_depth($id, $depth, $i);
}
elseif(is_page()) {
$depth = $wpdb->get_var("SELECT post_parent FROM $wpdb->posts WHERE ID = '".$depth."'");
$i++;
return get_depth($id, $depth, $i);
}
}
Assuming $cat to be the category ID of 'grandparent':
$number_of_subcategories = count(get_categories("echo=0&cat=" . $cat));
May help?
http://codex.wordpress.org/Function_Reference/get_categories
Try this one :
$args = array(
'type' => 'post',
'child_of' => 0,
'parent' => 0,
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => 1,
'hierarchical' => 0,
'exclude' => '',
'include' => '',
'number' => '',
'taxonomy' => 'category',
'pad_counts' => false
);
$cats = get_categories( $args );
foreach( $cats as $cat) {
if($cat->parent == 0) {
$parent_cat = null;
$head = $cat->name;
$head_id = $cat->term_id;
}
echo "<ul><a class='parent-category' href=''>" . $head . "</a>";
wp_list_cats("sort_column=NAME&optioncount=0&hierarchical=1&hide_empty=0&child_of={$head_id}&show_option_none=");
echo "</ul>";
}
Thanks.
I have a table in drupal which displays all the content from a table. I have added an edit link to each record . This link should take the user to the input form which has the values populated in it corresponding to the record. RIght now it is just populating the form with the last row.
For a row x, i need the form populated with the values for record x.
The table is created as
function _MYMODULE_sql_to_table($sql) {
$html = "";
// execute sql
$resource = db_query($sql);
// fetch database results in an array
$results = array();
while ($row = db_fetch_array($resource)) {
$results[] = $row;
$email = $row['p1'];
$comment = $row['p2'];
}
// ensure results exist
if (!count($results)) {
$html .= "Sorry, no results could be found.";
return $html;
}
// create an array to contain all table rows
$rows = array();
// get a list of column headers
$columnNames = array_keys($results[0]);
// loop through results and create table rows
foreach ($results as $key => $data) {
// create row data
$row = array(
'edit' => l(t('Edit'),"admin/content/test/$p1/$p2/Table1", $options=array()),);
// loop through column names
foreach ($columnNames as $c) {
$row[] = array(
'data' => $data[$c],
'class' => strtolower(str_replace(' ', '-', $c)),
);
}
// add row to rows array
$rows[] = $row;
}
// loop through column names and create headers
$header = array();
foreach ($columnNames as $c) {
$header[] = array(
'data' => $c,
'class' => strtolower(str_replace(' ', '-', $c)),
);
}
// generate table html
$html .= theme('table', $header, $rows);
return $html;
}
// then you can call it in your code...
function _MYMODULE_some_page_callback() {
$html = "";
$sql = "select * from {contactus}";
$html .= _MYMODULE_sql_to_table($sql);
return $html;
}
function display(){
$results = array();
$html = "";
$resource = db_query("select * from contactus");
$output = '';
while($row = db_fetch_array($resource)){
$results[] = $row;
}
if(!count($results)){
$html.= "Unable to display table";
return $html;
}
$rows = array();
$columnNames = array_keys($results[0]);
foreach($results as $key=>$data){
$row = array();
foreach($columnNames as $c){
$row = array(
'data' => $data[$c],
'class' => strtolower(str_replace(' ', '-', $c)),
);
}
$rows[] = $row;
}
$header = array();
foreach($columnNames as $c){
$header[] = array(
'data' => $c,
'class' => strtolower(str_replace(' ', '-', $c)),
);
}
$html .= theme('table', $header, $rows);
return $html;
}
You'll want to have $rows = array(); appear before your while loop. What you're doing is essentially destroying the array and redeclaring it as an empty array on each pass. This is why only the last row is appearing for you.