I'm trying to get a PHP Code to work in order to make a Database query within a Wordpress database table. The results (all distinct values of one specific column) should be put out within an HTML list. I want to be able to place the output everywhere in my content, so it should be accessable via shortcode.
Here's what I got so far. This code does not produce any errors in wordpress or the console, but it also doesn't do the trick... Nothing appears at the desired place.
class my_Shortcode {
var $echo;
function __construct() {
add_shortcode( 'my_plugin', array( $this, 'shortcode' ) );
}
function shortcode( $atts ) {
global $wpdb;
$table = isset( $atts['table'] ) ? $atts['table'] : false;
$column = isset( $atts['column'] ) ? $atts['column'] : false;
$listDisplay = isset( $atts['listDisplay'] ) ? $atts['listDisplay'] : false;
if ( $listDisplay == true ) {
if ( false != $table && false != $column ) {
$this->echo = "";
$results = $wpdb->get_results(
prepare('SELECT DISTINCT ' . $column . ' FROM ' . $table)
);
$this->echo .= "<div class=\"list\"><ul>";
foreach ($results as $result) {
$this->echo .= "<li>$result</li>\n";
}
$this->echo .= "</ul></div>";
return $this->echo;
}
}
}
}
I'm glad about any suggestions!
Do you want likve this?
<?php
echo do_shortcode("[my_plugin table='wp_posts' column=id]");
?>
class my_Shortcode {
var $echo;
function __construct() {
add_shortcode( 'my_plugin', array( $this, 'shortcode' ) );
}
function shortcode( $atts ) {
global $wpdb;
$table = isset( $atts['table'] ) ? $atts['table'] : false;
$column = isset( $atts['column'] ) ? $atts['column'] : false;
$listDisplay = isset( $atts['listDisplay'] ) ? $atts['listDisplay'] : true;
if ( $listDisplay == true ) {
if ( false != $table && false != $column ) {
$this->echo = "";
$results = $wpdb->get_results("SELECT DISTINCT $column FROM $table ",ARRAY_A);
$this->echo .= "<div class=\"list\"><ul>";
foreach ($results as $key => $result) {
$keys = array_keys( $result);
$this->echo .= '<li>'.$result[ $keys[0] ].'</li>\n';
}
$this->echo .= "</ul></div>";
return $this->echo;
}
}
}
}
$test = new my_Shortcode();
Related
I rephrase my question in this new post to which I have not had any answer. These two functions create a page on the user's account endpoint. A table is published on this page. I would like this table to be published in a new page / post of the site accessible to all. Any suggestions? Thank you
1 add_action( 'init', array(__CLASS__, 'wsc_add_my_account_endpoint') );
2 public static function wsc_add_my_account_endpoint() { add_rewrite_endpoint( 'wsc-share-cart', EP_ROOT | EP_PAGES ); }
3 The content that I would to print in a wordpress page:
if ( !isset($_GET['wc-wsc']) || !isset($_GET['nounce']) ) {
return;
}
if ( ! wp_verify_nonce( wc_clean($_GET['nounce']), 'wsc_save_share_cart' ) ) {
return;
}
$posted_fields = wc_clean($_POST);
$fields = get_option('wsc_form_fields');
$errors = array();
$form_submission = array();
$form_submission_html = '';
$customer_email = '';
if ( !empty($fields) ) {
$form_submission_html .= '<table>';
foreach ( $fields as $key => $field ) {
if ( true == $field['required'] && empty($posted_fields['wsc_form_field_' . esc_attr($key)]) ) {
$errors['wsc_form_field_' . esc_attr($key)] = wp_sprintf( '%s %s', esc_html__($field['label'], 'wc-wsc'), esc_html__('is required.', 'wc-wsc') );
}
$label = !empty($field['label']) ? $field['label'] : 'wsc_form_field_' . esc_attr($key);
$field_value = wc_clean($posted_fields['wsc_form_field_' . esc_attr($key)]);
if ( 'email' == $field['type'] ) {
if ( !is_email($field_value) ) {
$errors['wsc_form_field_' . esc_attr($key)] = wp_sprintf( '%s %s', esc_html__($field['label'], 'wc-wsc'), esc_html__('must be an email.', 'wc-wsc') );
}
$customer_email = $field_value;
}
if ( isset($posted_fields['wsc_form_field_' . esc_attr($key)]) ) {
$form_submission[$label] = $field_value;
}
$form_submission_html .= '<tr><th>' . esc_html($label) . '</th><td>' . esc_html($field_value) . '</td></tr>';
}
$form_submission_html .= '</table>';
} ```
I have done a change in the class-wc-product-cat-list-walker.php file and following is the changes in the code
public function start_el( &$output, $cat, $depth = 0, $args = array(), $current_object_id = 0 ) {
$cat_id = intval( $cat->term_id );
$output .= '<li class="cat-item cat-item-' . $cat_id;
if ( $args['current_category'] === $cat_id ) {
$output .= ' current-cat';
}
if ( $args['has_children'] && $args['hierarchical'] && ( empty( $args['max_depth'] ) || $args['max_depth'] > $depth + 1 ) ) {
$output .= ' cat-parent';
}
if ( $args['current_category_ancestors'] && $args['current_category'] && in_array( $cat_id, $args['current_category_ancestors'], true ) ) {
$output .= ' current-cat-parent';
}
$pageurl = wp_get_referer();
$template = basename($pageurl);
$post_id = get_the_ID();
$catpage = get_field( 'catelog_page', $post_id );
$catalogpage = 'no';
if (isset($_GET['catalog'])) {
$catalogpage = 'yes';
}
if ( $catpage == TRUE || $catalogpage=='yes' ) {
$output .= '">' . apply_filters( 'list_product_cats', $cat->name, $cat ) . '';
}
else {
$output .= '">' . apply_filters( 'list_product_cats', $cat->name, $cat ) . '';
}
if ( $args['show_count'] ) {
$output .= ' <span class="count">(' . $cat->count . ')</span>';
}
}
I want to keep it in the child theme and make it functional. Is there any way? I have tried to copy the file and paste it in the child theme WooCommerce folder. but it is not working.
please help me to know the way to change it. Thanks in advance.
You can create your own custom class and try to override WC_Product_Cat_List_Walker.
So you can do something like this
class Custom_WC_Product_Cat_List_Walker extends WC_Product_Cat_List_Walker {
/**
* What the class handles.
*
* #var string
*/
public $tree_type = 'product_cat';
/**
* DB fields to use.
*
* #var array
*/
public $db_fields = array(
'parent' => 'parent',
'id' => 'term_id',
'slug' => 'slug',
);
public function start_el( &$output, $cat, $depth = 0, $args = array(), $current_object_id = 0 ) {
$cat_id = intval( $cat->term_id );
$output .= '<li class="cat-item cat-item-' . $cat_id;
if ( $args['current_category'] === $cat_id ) {
$output .= ' current-cat';
}
if ( $args['has_children'] && $args['hierarchical'] && ( empty( $args['max_depth'] ) || $args['max_depth'] > $depth + 1 ) ) {
$output .= ' cat-parent';
}
if ( $args['current_category_ancestors'] && $args['current_category'] && in_array( $cat_id, $args['current_category_ancestors'], true ) ) {
$output .= ' current-cat-parent';
}
$pageurl = wp_get_referer();
$template = basename($pageurl);
$post_id = get_the_ID();
$catpage = get_field( 'catelog_page', $post_id );
$catalogpage = 'no';
if (isset($_GET['catalog'])) {
$catalogpage = 'yes';
}
if ( $catpage == TRUE || $catalogpage=='yes' ) {
$output .= '">' . apply_filters( 'list_product_cats', $cat->name, $cat ) . '';
}
else {
$output .= '">' . apply_filters( 'list_product_cats', $cat->name, $cat ) . '';
}
if ( $args['show_count'] ) {
$output .= ' <span class="count">(' . $cat->count . ')</span>';
}
}
}
Then you can call that function like this
add_filter('woocommerce_product_categories_widget_args', 'custom_product_categories_widget_args', 10, 1);
function custom_product_categories_widget_args($args) {
$args['walker'] = new Custom_WC_Product_Cat_List_Walker;
return $args;
}
Just use this code in your active theme functions.php file and check.
I have a PHP function that takes a table that has been filtered using gravity flow. This function loops through each row of the table. I want to change the styling of this table. I have a specific CSS class I want the table styling to have. This class is "tr-shadow". I would apply this CSS class to each row of the table. I have a $style variable that is used for the CSS. How do I add the CSS class as a string for the $style variable so that the table can print out with the CSS from that class? Here is the code below.
'''
public function single_row_columns( $item ) {
list( $columns, $hidden ) = $this->get_column_info();
foreach ( $columns as $column_name => $column_display_name ) {
$class = "class='$column_name column-$column_name'";
$style = "class='tr-shadow'";
if ( in_array( $column_name, $hidden ) ) {
$style = "class='tr-shadow'";
}
$data_label = ( ! empty( $column_display_name ) ) ? " data-label='$column_display_name'" : '';
$attributes = "$class$style$data_label";
if ( 'cb' == $column_name ) {
echo '<th data-label="' . esc_html__( 'Select', 'gravityflow' ) . '" scope="row" class="check-column">';
echo $this->column_cb( $item );
echo '</th>';
} elseif ( method_exists( $this, 'column_' . $column_name ) ) {
echo "<td $attributes>";
echo call_user_func( array( $this, 'column_' . $column_name ), $item );
echo '</td>';
} else {
echo "<td $attributes>";
echo $this->column_default( $item, $column_name );
echo '</td>';
}
}
}
'''
As you can see I have already tried adding "$style="class='tr-shadow". However, this doesn't add any style to the tables. I am assuming that I am not correctly formatting the $style variable in a way that the css class is recognizable. How can I use the $style variable to successfully output the css class to each row of the table.
Your $style variable is including the attribute style again, which will result in something like:
class="column_name column-bar class=' ...
which is invalid.
I'd recommend changing your code to something like this:
public function single_row_columns( $item ) {
list( $columns, $hidden ) = $this->get_column_info();
foreach ( $columns as $column_name => $column_display_name ) {
$class = "$column_name column-$column_name";
$class .= " tr-shadow";
if ( in_array( $column_name, $hidden ) ) {
$class .= " tr-shadow";
}
$data_label = ( ! empty( $column_display_name ) ) ? " data-label='$column_display_name'" : '';
$attributes = "$data_label";
if ( 'cb' == $column_name ) {
echo '<th data-label="' . esc_html__( 'Select', 'gravityflow' ) . '" scope="row" class="check-column">';
echo $this->column_cb( $item );
echo '</th>';
} elseif ( method_exists( $this, 'column_' . $column_name ) ) {
echo "<td class=\"$class\" $attributes>";
echo call_user_func( array( $this, 'column_' . $column_name ), $item );
echo '</td>';
} else {
echo "<td class=\"$class\" $attributes>";
echo $this->column_default( $item, $column_name );
echo '</td>';
}
}
}
Also, it looks like class is always tr-shadow regardless of what you do.
In this code fragment you set the classes:
$class = "class='$column_name column-$column_name'";
$style = "class='tr-shadow'";
And then you concatenate it in one string:
$attributes = "$class$style$data_label";
So that, I think your second class is ignored.
I'm running into an issue in my CakePHP (2.4.1) app where the virtual field in one of my models is not properly being decrypted using Cake's Security::rijndael(). In my User model, the display field is defined as
public $virtualFields = array( 'name' => 'CONCAT(User.first_name, " ", User.last_name)' );
Both User.first_name and User.last_name are encrypted, and User.name is the displayField for the model. In the AssignedShift related model (User hasMany AssignedShift), the User.name field is not being properly decrypted. Here is an example return:
Array(
[1] => Test|�d�F�3��������������S0�Dy=>�dJ���sP�4�F�n�s-#���7P���n�ʙ.�C�#���˷C�z��(;Eu)�
)
This is the only model that this happens on, so I'm pretty confident my afterFind method is working properly. In any case, below are the functions for encrypt/decrypt:
/*AppModel.php*/
function _afterFind($results, $primary) {
if( $primary ) {
foreach( $results as $key => $val) {
if( isset( $val[$this->alias] ) ) {
$results[$key][$this->alias] = $this->doAfterFind( $results[$key][$this->alias] );
}
}
} else {
if( isset( $results['id']) ) {
$results = $this->doAfterFind($results);
} else {
foreach( $results as $key => $val ) {
if( isset( $val[$this->alias] ) ) {
if( isset( $val[$this->alias]['id'] ) ) {
$results[$key][$this->alias] = $this->doAfterFind( $results[$key][$this->alias] );
} else {
foreach( $results[$key][$this->alias] as $key2 => $val2 ) {
$results[$key][$this->alias][$key2] = $this->doAfterFind( $results[$key][$this->alias][$key2] );
}
}
}
}
}
}
return $results;
}
public function doAfterFind($data) {
foreach( $data as $key => $val) {
if( !empty( $val ) && strlen( $val ) >= 88) {
$data[$key] = Security::rijndael( base64_decode( $val ), Configure::read( 'Security.cipherSeed' ), 'decrypt' );
}
}
//My attempt at hacking it back together
if(array_key_exists('first_name', $data)) {
$data['name'] = $data['first_name'] ." ". $data['last_name'];
}
return $data;
}
/*AssignedShift.php*/
public function afterFind($results, $primary = false) {
return $this->_afterFind($results, $primary);
}
Both models were created from the console - User has been modified but I haven't touched the relationships, and AssignedShift is completely untouched. Any ideas? Thanks in advance.
I have the following code:
$data = file_get_contents('http://www.robotevents.com/robot-competitions/vex-robotics-competition?limit=all');
echo "Downloaded";
$dom = new domDocument;
#$dom->loadHTML($data);
$dom->preserveWhiteSpace = false;
$tables = $dom->getElementsByTagName('table');
$rows = $tables->item(2)->getElementsByTagName('tr');
foreach ($rows as $row) {
$cols = $row->getElementsByTagName('td');
for ($i = 0; $i < $cols->length; $i++) {
echo $cols->item($i)->nodeValue . "\n";
}
}
The final field has an Link which I need to store the URL of. Also, The script outputs characters such as "Â". Does anyone know how to do/fix these things?
I would recommend not using DOM to parse HTML, as it has problems with invalid HTML. INstead use regular expression
I use this class:
<?php
/**
* Class to return HTML elements from a HTML document
* #version 0.3.1
*/
class HTMLQuery
{
protected $selfClosingTags = array( 'area', 'base', 'br', 'hr', 'img', 'input', 'link', 'meta', 'param' );
private $html;
function __construct( $html = false )
{
if( $html !== false )
$this->load( $html );
}
/**
* Load a HTML string
*/
public function load( $html )
{
$this->html = $html;
}
/**
* Returns elements from the HTML
*/
public function getElements( $element, $attribute_match = false, $value_match = false )
{
if( in_array( $element, $this->selfClosingTags ) )
preg_match_all( "/<$element *(.*)*\/>/isU", $this->html, $matches );
else
preg_match_all( "/<$element(.*)>(.*)<\/$element>/isU", $this->html, $matches );
if( $matches )
{
#Create an array of matched elements with attributes and content
foreach( $matches[0] as $key => $el )
{
$current_el = array( 'name' => $element );
$attributes = $this->parseAttributes( $matches[1][$key] );
if( $attributes )
$current_el['attributes'] = $attributes;
if( $matches[2][$key] )
$current_el['content'] = $matches[2][$key];
$elements[] = $current_el;
}
#Return only elements with a specific attribute and or value if specified
if( $attribute_match != false && $elements )
{
foreach( $elements as $el_key => $current_el )
{
if( $current_el['attributes'] )
{
foreach( $current_el['attributes'] as $att_name => $att_value )
{
$keep = false;
if( $att_name == $attribute_match )
{
$keep = true;
if( $value_match == false )
break;
}
if( $value_match && ( $att_value == $value_match ) )
{
$keep = true;
break;
}
elseif( $value_match && ( $att_value != $value_match ) )
$keep = false;
}
if( $keep == false )
unset( $elements[$el_key] );
}
else
unset( $elements[$el_key] );
}
}
}
if( $elements )
return array_values( $elements );
else
return array();
}
/**
* Return an associateive array of all the form inputs
*/
public function getFormValues()
{
$inputs = $this->getElements( 'input' );
$textareas = $this->getElements( 'textarea' );
$buttons = $this->getElements( 'button' );
$elements = array_merge( $inputs, $textareas, $buttons );
if( $elements )
{
foreach( $elements as $current_el )
{
$attribute_name = mb_strtolower( $current_el['attributes']['name'] );
if( in_array( $current_el['name'], array( 'input', 'button' ) ) )
{
if( isset( $current_el['attributes']['name'] ) && isset( $current_el['attributes']['value'] ) )
$form_values[$attribute_name] = $current_el['attributes']['value'];
}
else
{
if( isset( $current_el['attributes']['name'] ) && isset( $current_el['content'] ) )
$form_values[$attribute_name] = $current_el['content'];
}
}
}
return $form_values;
}
/**
* Parses attributes into an array
*/
private function parseAttributes( $str )
{
$str = trim( rtrim( trim( $str ), '/' ) );
if( $str )
{
preg_match_all( "/([^ =]+)\s*=\s*[\"'“”]{0,1}([^\"'“”]*)[\"'“”]{0,1}/i", $str, $matches );
if( $matches[1] )
{
foreach( $matches[1] as $key => $att )
{
$attribute_name = mb_strtolower( $att );
$attributes[$attribute_name] = $matches[2][$key];
}
}
}
return $attributes;
}
}
?>
Usage is:
$c = new HTMLQuery();
$x = $c->getElements( 'tr' );
print_r( $x );