Kartik's star-rating widget: Plugin Methods - yii2

INTRODUCTION:
I have a blog maked on Yii2. The widget used for making rating is:
http://demos.krajee.com/widget-details/star-rating#basic-usage
http://plugins.krajee.com/star-rating#installation
Each post from blog have his AVERAGE RATING that is read from database.
After the user selects his own rating - segregate rating, the AVERAGE RATING is calculated in RatingController and recorded in database.
QUESTION:
How dynamically show the new calculated rating (AVERAGE RATING) after the user clicked on the star? Now for exemple (exemple with 2 voters) if the average rating is 4.5 and the user chooses for exemple 3.5, then after that it shows 3.5 instead 4. If updating page than it's ok, it shows 4. How to apply "Plugin Methods"?, for example 'update' or 'refresh'?

Well the concept is simple if you concentrate you have to update the ratings as soon as you click on the star and then you want to update the rating you need to use the plugin events and methods provided namely rating:change and update, use the rating:change to detect the click and make an ajax post request to the controller/action to update the rating in database ,and then send back the new rating as the response, then in the ajax success function update the star rating plugin with the new rating.
I will add the code that would emphasize the main logic rather than calculating the average.
Your star rating input code will look like the following look into the success function to see how to call the update method of starrating.
echo $formReview->field ( $review , 'rate' , [ 'inputOptions' =>
[ 'class' => 'form-control' ] ] )->widget ( StarRating::classname () , [
'pluginOptions' => [
'step' => 0.50 ,
'showClear' => true ,
'showCaption' => true ,
'filledStar' => '<i class="zmdi zmdi-star"></i>' ,
'emptyStar' => '<i class="zmdi zmdi-star-outline"></i>' ,
] ,
'pluginEvents' => [
'rating:change' => "function(event, value, caption){
$.ajax({
url:'path/to/update-rating',
method:'post',
data:{rate:value},
dataType:'json',
success:function(data){
$(event.currentTarget).rating('update',data.rating);
}
});
}"
]
] )->label ( false );
in your controller/action
public function actionUpdateRating() {
$response['success'] = false;
if ( Yii::$app->request->post () ) {
$id = Yii::$app->request->post ( 'blog_id' );
$model = Blog::findOne ( $id );
//update your database with the new rating
//............
//get new rating in $newRating
$response['rating'] = $newRating;
$response['success'] = true;
}
echo Json::encode ( $response );
Yii::$app->end ();
}

Related

ACF front end form to update term

I want to use ACF frontend form function to create a form with custom fields
I see this issue for create new term, #Alhana
ACF front end form to create term
but I want to generate the form with old data
Well, i didn't see that question, but if it's still actual, here's a solution.
First of all, make sure you have ACF group, linked to your taxonomy. You will need ID of this group, it can be found in url on group edit page, for example:
http://site.ru/wp-admin/post.php?post=340&action=edit
In this case group ID is 340. If you don't want to use hardcoded ID (if your groups are changing from time to time), you can get it, using group name (in this example group name is Technic CPT):
global $wpdb;
$group_ID = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_title = 'Technic CPT'" );
Then, you'll need ID of term you're updating. I think, it's not nesessary to write about getting it since it's WP basics :) You'll end with something like this:
$term_id = 405;
And finally, you'll need your taxonomy's slug. In this example it's technic. So, let's render our form!
acf_form_head();
$acf_form_args = array(
'id' => 'technic_edit_form',
'post_id' => 'technic_'.$term_id,
'form' => true,
'submit_value' => 'Update technic',
'field_groups' => array($group_ID),
'updated_message' => 'Technic is updated!';
);
acf_form( $acf_form_args );
Now your term's custom fields will be shown in this form. But to save term data after editing you'll need to add some more code. ACF form assumes that you're saving post data, we'll add some logic to detect saving data for term.
add_filter( 'acf/pre_save_post', 'acf_handle_form_save', 10, 1 );
function acf_handle_form_save( $post_id ) {
// Function accepts id of object we're saving.
// All WordPress IDs are unique so we can use this to check which object it is now.
// We'll try to get term by id.
// We'll get term id with added taxonomy slug, for example 'technic_405'.
// For checking term existence we must cut out this slug.
$cut_post_id = str_replace( 'technic_', '', $post_id );
$test_tax_term = get_term_by( 'id', $cut_post_id, 'technic' );
// If $test_tax_term is true - we are saving taxonomy term.
// So let's change form behaviour to saving term instead of post.
if ( $test_tax_term ) :
// Get array of fields, attached to our taxonomy
global $wpdb;
$group_ID = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_title = 'Technic CPT'" );
$acf_fields = acf_get_fields_by_id( $group_ID );
// Then sanitize fields from $_POST
// All acf fields will be in $_POST['acf']
foreach ( $acf_fields as $acf_field ) :
$$acf_field[ 'name' ] = trim( esc_attr( strip_tags( $_POST[ 'acf' ][ $acf_field[ 'key' ] ] ) ) );
endforeach;
// We need to have some fields in our group, which are just duplicates of standard term fields: name, slug, description.
// In this example it's only one field - term name, called 'technic_name'.
$name = 'technic_name';
// Update base term info, in this example - only name.
$term = wp_update_term( $cut_post_id, 'technic', array( 'name' => $$name ) );
// If all is correct, update custom fields:
if ( !is_wp_error( $term ) ) :
foreach ( $acf_fields as $acf_field ) :
update_field( $acf_field[ 'name' ], $$acf_field[ 'name' ], 'technic_' . $cut_post_id );
endforeach;
endif;
else :
// Here is saving usual post data. Do what you need for saving it or just skip this point
endif;
return $post_id;
}
Please note: validation of $_POST data may be more complex. For example, you may have to validate array of values if there are ACF galleries or relationships among your taxonomy fields. In my example i have only common text fields.
Hope that helps!
The answer from Alhana worked for me with one change. The term object works if sent as the the value for the post_id:
$term_obj = get_term($term_id);
$acf_form_args = array(
'post_id' => $term_obj,
'post_title' => false,
'submit_value' => 'Update Term',
'field_groups' => array($group_ID),
);

Show message if no orders in woocommerce

I would like to display a message in my-account if the customer has no orders I would like to show "No orders currently".
I guessing there's a function I could use to hook into this somewhere?
Had a good search and cant find anything to get me started.
Thanks.
Modifying from this tutorial I think this would work:
function wc_get_customer_orders() {
// Get all customer orders
$customer_orders = get_posts( array(
'numberposts' => 1,
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(),
'post_type' => wc_get_order_types(),
'post_status' => array_keys( wc_get_order_statuses() ),
) );
$customer = wp_get_current_user();
// Text for our message
$notice_text = sprintf( 'Hey %1$s 😀 We noticed you haven\'t placed any orders with us.', $customer->display_name );
// Display our notice if the customer has no orders
if ( count( $customer_orders ) == 0 ) {
wc_print_notice( $notice_text, 'notice' );
}
}
add_action( 'woocommerce_before_my_account', 'wc_get_customer_orders' );
Basically, on the account page we query for a single order by the currently logged in user. If we don't get an order back we show the notice.
Copied my-orders.php to local folder and added an else clause:
else{
echo "No orders";
}
This can be styled using WC css

Laravel - Create or Update by defined attributes

I have this this table:
--Votes--
id: Integer
post_id: Integer
user_id: Integer
positive: Boolean
Now I would like to create a record only if it not exists. It is working until someone wants to click on dislike after he clicked on like(on the other side exactly equivalent).
For example someone likes a post a record will be created with positive=true. Now if the user clicks on the same post but this time on dislike, it will be created another record, but i want that it only updates the existing record.
Is there a simple solution?
Here is my Code to create the record:
$vote = Vote::firstOrCreate(array(
'post_id' => $request->input('post_id'),
'user_id' => Auth::user()->id,
'positive' => $request->input('positive')
));
Note: If someone knows how to do that, maybe he could show me how a deletion would be. For example someone clicks on like two times. The record should be created an deleted.
You can use updateOrCreate method:
public static function updateOrCreate(array $attributes, array $values = array())
{
$instance = static::firstOrNew($attributes);
$instance->fill($values)->save();
return $instance;
}
have a look: https://github.com/laravel/framework/blob/5.0/src/Illuminate/Database/Eloquent/Model.php#L605
EDIT:
Example
$attributes = [
'name' => 'Christian',
'email' => 'christian#example.com'
];
$values = [
'name' => 'Christian',
'email' => 'christian#example.com',
'phone' => '123456789'
];
MyModel::updateOrCreate($attributes, $values);
In the example above I will search if in my table I have an entry which match name and email, if it exists I will update the records, otherwise I will insert a new entry with the $values infos

Retrieving and posting static dropdown data into mysql database in Zend 2

I have several fields in my form that i wish to post to the database. All the other fields bar the dropdown field are all working fine
The official documentation for zend 2 is not really clear on how to deal with posting data from a dropdown menu into the database
Here's what i have:
my addAction in the controller
public function addAction()
{
$form = new UsersForm();
$form->get('submit')->setValue('Add');
$request = $this->getRequest();
if ($request->isPost())
{
$users = new Users();
$form->setInputFilter($users->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid())
{
$users->exchangeArray($form->getData());
$this->getUsersTable()->saveUser($users);
// Redirect to list of albums
return $this->redirect()->toRoute('index');
}
}
return array('form' => $form);
}
my form
public function __construct($name = null)
{
// we want to ignore the name passed
parent::__construct('users');
//other form elements...
//the dropdown menu
$this->add(array(
'type' => 'Select',
'name' => 'groupid',
'options' => array(
'label' => 'Group',
'value_options' => array(
'0' => 'Not Selected',
'1' => 'Super Admin',
'2' => 'Company Admin',
),
),
));
//...
}
}
the view
<?php
$form->setAttribute('action', $this->url('user', array('action' => 'add')));
$form->prepare();
echo $this->form()->openTag($form);
echo $this->formRow($form->get('groupid'));
echo $this->formSubmit($form->get('submit'));
echo $this->form()->closeTag();
When i run my application for the addAction, i get an error message:
Statement could not be executed (23000 - 1048 - Column 'GroupID' cannot be null)
where 'GroupID' is the column in my table that takes the value from the dropdown which means the field is not being posted
I need help on this
If the column in your database is GroupID, the form element should also be named that. Yours is groupid (i.e. lowercase). If that doesn't fix the issue, please edit your question to include the DB structure and the code for the saveUser() function.

Retrieve value from new column

I am trying to learn opencart structure, and trying to create a new column under the table product. The new column is "test"
Then I try to retrieve the data under this page index.php?route=checkout/cart (replace price with test column)
catalog\controller\checkout\cart.php
...
$this->data['products'][] = array(
'key' => $product['key'],
'thumb' => $image,
'name' => $product['name'],
'model' => $product['model'],
'option' => $option_data,
'quantity' => $product['quantity'],
'stock' => $product['stock'] ? true : !(!$this->config->get('config_stock_checkout') || $this->config->get('config_stock_warning')),
'reward' => ($product['reward'] ? sprintf($this->language->get('text_points'), $product['reward']) : ''),
'price' => $product['test'], //<-- new column
'total' => $total,
'href' => $this->url->link('product/product', 'product_id=' . $product['product_id']),
'remove' => $this->url->link('checkout/cart', 'remove=' . $product['key'])
);
The problem is I'm not getting any output, and I'm not sure how to work with the model. Which query/function is related with this page ?
The problem is that the $products that are available at cart.php controller are retrieved from the session where they have been stored in previously set structure, so there is no test index and You should get a Notice: undefined index 'test' in .... The $products are retrieved by
foreach ($this->cart->getProducts() as $product) {
//...
}
See /system/library/cart.php and method getProducts() to understand what I am speaking about.
If You would like to use this at catalog/controller/product/category.php or catalog/controller/product/product.php controllers, the code You are trying will work.
If You replace the price within all product lists and product detail, these controllers:
product/
category.php
manufacturer_info.php
product.php
search.php
special.php
module/
bestseller.php
featured.php
latest.php
special.php
with Your value, the final price within cart would be Your test value.