Forum for discussing general topics related to Couch.
7 posts Page 1 of 1
Hello and Greetings to one and all and KK Sir.

I am trying to do a Rating and Review system for an ecommerce site.

I am using the following:
1. Comment System (viewtopic.php?f=8&t=8397)
2. Votes, Ratings & Polls Module (viewtopic.php?f=5&t=8133)

What I have:
1. product.php (holding the products, clonable template and the couch cart)
2. review.php (holding the product id on which review is being posted, user id of the user posting the review, the review, star rating given by the user)

review.php template
Code: Select all
<?php require_once( 'couch/cms.php' ); ?>
<cms:template title='Product Comments' clonable='1' parent="_product_" executable='0' order="4" >
   <cms:editable name='ticket_comments' type='relation' label="Product Reviewed" masterpage='product.php' has='one' order="1" required="1" />
   <cms:editable name='username' type='relation' label='Username' masterpage='users/index.php' has='one' order="2" required="1" />
   <cms:editable name='review' type='textarea' label='Review' order="3" required="1" />
   <cms:editable name='rating_by_user' label="Rating by User" type='text' order="4" />
</cms:template>
<?php COUCH::invoke(); ?>


Snippet from the product.php template that is implementing the review and rating
Code: Select all
<cms:editable name="rating" label="Product Rating" type="group" order="12" />
    <cms:editable name='rating_product' label="Product Rating" type='vote_stars' search_type='decimal' allow_zero_stars='0' group="rating" order="1" />

Code: Select all
<cms:form 
    masterpage='review.php'
    mode='create'
    enctype='multipart/form-data'
    method='post'
    anchor='0'
>
    <cms:if k_success >
      <!-- New Review Added -->
      <!-- k_page_title = Product Page Id - User Id -->
       <cms:db_persist_form
           _invalidate_cache='0'
           _auto_title='0'
           k_page_title = "<cms:show product_id_rating />-<cms:show k_user_id />"
           username=k_user_id
            ticket_comments=k_page_id
            rating_by_user = frm_rating_by_user
       />

       <cms:if k_success>
          <!-- Star Rating Update -->
          <cms:db_persist
             _masterpage="product.php"
             _mode='edit'
             _page_id=product_id_rating
            
             rating_product = frm_rating_by_user
         />                                          
                        <cms:set_flash name='submit_success' value='1' />
         <cms:redirect k_page_link />
      </cms:if>
   </cms:if>


    <cms:if k_error >
        <div class="row">
            <cms:each k_error >
               <div class="col-md-12">
                   <div class="alert alert-danger shadow-z-1">
                      <cms:show item />
                   </div>
               </div>
            </cms:each>
        </div>
    </cms:if>   


   <cms:if "<cms:not submit_success />" >
      <div class="col-md-3">
            <strong>Your Rating</strong>
            <div class="gxcpl-ptop-5"></div>
          <cms:input type='bound' name='rating_by_user' opt_values='1 | 2 | 3 | 4 | 5' />
            <div class="gxcpl-ptop-10"></div>
        </div>
       
        <div class="col-md-9">
           <cms:hide>
                <cms:input type="bound" name="review" placeholder="Your Review" class="form-control" />
            </cms:hide>
            <textarea name="f_review" class="form-control" placeholder="Your Review" validator_msg="required=You cannot submit a blank review" required="1"></textarea>
            <div class="gxcpl-ptop-10"></div>                       
        </div>
        <div class="col-md-12 text-center">
            <cms:input type="submit" class="btn gxcpl-btn-grey-blue" value="SUBMIT REVIEW" name="submit"/>
            <div class="gxcpl-ptop-40"></div>
        </div>
   </cms:if>
</cms:form>


The Issue
The review gets saved as intended, but the rating doesnot. What happens is that only the latest rating gets saved. while the remaining do not.
For example, if I give a 4-star rating, its saves in the backend. Now when I give a new rating, lets say 1 star, this saves in the back end, but the total votes are always shown to be 1.
How can all the star ratings be saved in the backend?

Thanks in advance.

Regards,
GenXCoders
Image
where innovation meets technology
Hi Aashish,

The 'votes' module was coded to work with the 'members' module - the 'extended-users' module has long since supplanted the 'members' module but the votes module, unfortunately, has not been updated to work with the new addon.

That said, the votes module only uses the info of whether or not a 'member' is logged-in to prevent users from casting their votes multiple times.
If a member ID is not found, the visitor is considered to be anonymous and then her IP address is used instead to prevent multiple voting (how long the same visitor is not allowed a second vote can be set from the config file present within the votes folder - for anonymous it is 6 hours by default).

So, the votes module can still work but will consider all visitors to be anonymous and will try to stop visitors from the same IP to vote multiple times.

That is what seems to be happening in your case -
you are testing the votes from the same IP and the module considers it a vote of the same user and so will update the last vote instead of creating a new entry.

Since you are using Couch's other features (relations etc.) to allow only logged-in users to vote and vote only once on a product, you don't need the votes module to exercise its default constraints.

To do that, edit addons/votes/config.php and set the 'define' shown below to '0' -
Code: Select all
// 2.
// Same as above but applies to anonymous voters (i.e. visitors that are not registered members).
// Since non-members can only be tracked by their IPs, this window should be kept small enough to allow
// visitors potentially sharing the same IP address to vote,
define( 'K_VOTE_WINDOW_ANON', 6 * 60 * 60 ); // time in seconds. Default 6 hours

i.e. make it as follows -
Code: Select all
define( 'K_VOTE_WINDOW_ANON', 0 );

And that should now allow multiple votes from the same IP address too.

Hope this helps.
@KK Sir,
Thanks a lot for posting the solution and its detailed explanation. As always, it indeed helps. I confirm that the review and rating module is working perfectly.
I will post the final barebone code here, so that it comes in handy for others.
Regards,
Aashish
Image
where innovation meets technology
Hello Aashish,

did you ever get a chance to post this code? Is it still working?
@scratz,

Yes the code is a working code. I will ask Aashish Sir to post it here. The code was not posted earlier.

Regards,
GXCPL (CTR)
Image
where innovation meets technology
@scratz,
Greeting!

This is the code:

Code: Select all
<!-- Title -->
<div class="row">
   <div class="col-md-12">
      <h4 class="gxcpl-no-margin gxcpl-block-title">
           Post Your Review
       </h4>
       <div class="gxcpl-ptop-20"></div>
   </div>
</div>
<!-- Title -->

<!-- Check if user is logged in -->
<cms:if k_logged_in>
   <div class="row">
        <div class="col-md-12">
            <!-- Logged in User: Display a message to show which user is rating what product -->
            Reviewing product as <b><cms:show user_fname_display /></b>. <a href="<cms:show k_logout_link />" onclick="if( confirm('Are you sure you want to logout?') ) { return true; } return false;">Logout</a> if its not you!
            <div class="gxcpl-ptop-20"></div>
            <!-- Logged in User: Display a message to show which user is rating what product -->
        </div>
    </div>
   <cms:set submit_success="<cms:get_flash 'submit_success' />" />
   <cms:if submit_success >
      <cms:redirect k_page_link />
   </cms:if>
   <cms:pages masterpage="product.php" id=k_page_id limit="1">
      <cms:set product_id_rating="<cms:show k_page_id />" scope="global" />
   </cms:pages>

    <!-- Checking if user has already rated and reviewed -->
    <cms:set my_template_name = 'review.php' />
    <cms:set my_page_title = "<cms:show product_id_rating />-<cms:show k_user_id />" />
    <cms:php>
        global $CTX, $FUNCS;
        $name = $FUNCS->get_clean_url( "<cms:show my_page_title />" );
        $CTX->set( 'my_page_name', $name );
    </cms:php>
    <cms:set my_page_id = '' 'global' />
    <cms:pages masterpage=my_template_name page_name=my_page_name limit='1' show_future_entries='1'>
        <cms:set my_page_id=k_page_id  'global' />
    </cms:pages>
    <!-- If my_page_id is 'blank' then user has not rated the product and hence we show them the form for rating the product -->
    <cms:if my_page_id=''>
   <cms:form
       masterpage='review.php'
       mode='create'
       enctype='multipart/form-data'
       method='post'
       anchor='0'
   >
       <cms:if k_success >
           <!-- k_page_title = Product Page Id - User Id -->
          <cms:db_persist_form
              _invalidate_cache='0'
              _auto_title='0'
              k_page_title = "<cms:show product_id_rating />-<cms:show k_user_id />"
              username=k_user_id
               ticket_comments=k_page_id
               rating_by_user = frm_rating_by_user
          />

          <cms:if k_success>
             <!-- Star Rating Update -->
             <cms:db_persist
                _masterpage="product.php"
                _mode='edit'
                _page_id=product_id_rating
               
                rating_product = frm_rating_by_user
            />                                          
            <cms:set_flash name='submit_success' value='1' />
            <cms:redirect k_page_link />
         </cms:if>
      </cms:if>


       <cms:if k_error >
           <div class="row">
               <cms:each k_error >
                  <div class="col-md-12">
                      <div class="alert alert-danger shadow-z-1">
                         <cms:show item />
                      </div>
                  </div>
               </cms:each>
           </div>
       </cms:if>   


      <cms:if "<cms:not submit_success />" >

         
         <div class="col-md-3">
                <strong>Your Rating</strong>
                <div class="gxcpl-ptop-5"></div>
               <cms:hide>
                <cms:input type='bound' name='rating_by_user' opt_values='1 | 2 | 3 | 4 | 5' /><br>
             </cms:hide>
             <div class="rating">
                  <input type="radio" id="star5" name="f_rating_by_user" value="5" class="star" /><label for="star5" title="Rocks!"></label>
                <input type="radio" id="star4" name="f_rating_by_user" value="4" /><label for="star4" title="Pretty good"></label>
                <input type="radio" id="star3" name="f_rating_by_user" value="3" /><label for="star3" title="Meh"></label>
                <input type="radio" id="star2" name="f_rating_by_user" value="2" /><label for="star2" title="Kinda bad"></label>
                <input type="radio" id="star1" name="f_rating_by_user" value="1" /><label for="star1" title="Sucks big time"></label>
            </div>
               <!-- <i class="fa fa-star-o fa-lg gxcpl-fc-golden"></i> <i class="fa fa-star-o fa-lg gxcpl-fc-golden"></i> <i class="fa fa-star-o fa-lg gxcpl-fc-golden"></i> <i class="fa fa-star-o fa-lg gxcpl-fc-golden"></i> <i class="fa fa-star-o fa-lg gxcpl-fc-golden"></i> -->
                <div class="gxcpl-ptop-10"></div>
            </div>
           
            <div class="col-md-9">
               <cms:hide>
                    <cms:input type="bound" name="review" placeholder="Your Review" class="form-control" />
                </cms:hide>
                <textarea name="f_review" class="form-control" placeholder="Your Review" validator_msg="required=You cannot submit a blank review" required="1"></textarea>
                <div class="gxcpl-ptop-10"></div>                       
            </div>
            <div class="col-md-12 text-center">
                <cms:input type="submit" class="btn gxcpl-btn-grey-blue" value="SUBMIT REVIEW" name="submit"/>
                <div class="gxcpl-ptop-40"></div>
            </div>
      </cms:if>
   </cms:form>

       <!-- If user has already rated the product, then display this message -->
   <cms:else />
      <div class="row">
         <div class="col-md-12">
            <div class="alert alert-warning shadow-z-1 text-center">
               You have already reviewed and rated the product. Thank You!
            </div>
         </div>
      </div>
        <!-- If user has already rated the product, then display this message -->
   </cms:if>   
<!-- Check if user is logged in -->

<!-- If user is logged out, ask to signin -->
<cms:else_if k_logged_out />
   <button class="btn gxcpl-btn-orange-2" type="button" onclick="window.location.href='<cms:show k_login_link />';">
        <i class="fa fa-lock"></i> SIGN IN
    </button>
    <div class="gxcpl-ptop-20"></div>
</cms:if>
<!-- If user is logged out, ask to signin -->


The CSS for the stars to work:
Include fontawesome (I had used v4.7)
Code: Select all
<link rel="stylesheet" type="text/css" href="http://localhost/CTO/thedashami.com/assets/css/font-awesome.css" />

for the stars to appear and the css code below to display the stars
Code: Select all
.rating {
   float: left;
   border: none;
}
.rating:not(:checked) > input {
    position:absolute;
    top:-9999px;
    clip:rect(0,0,0,0);
    visibility: hidden;
}
.rating:not(:checked) > label {
    float:right;
    width:1em;
    padding:0 .1em;
    overflow:hidden;
    white-space:nowrap;
    cursor:pointer;
     font-family: FontAwesome;
    font-size:200%;
    line-height:1.2;
    color:#ddd;
}
.rating:not(:checked) > label:before {
    content: "\f005";
}
.rating > input:checked ~ label {
    color: #f70;
}
.rating:not(:checked) > label:hover,
.rating:not(:checked) > label:hover ~ label {
    color: gold;
}
.rating > input:checked + label:hover,
.rating > input:checked + label:hover ~ label,
.rating > input:checked ~ label:hover,
.rating > input:checked ~ label:hover ~ label,
.rating > label:hover ~ input:checked ~ label {
    color: #ea0;
}
.rating > label:active {
    position:relative;
    top:2px;
    left:2px;
}


Please let me know if this helps!

Regards,
Aashish
GXCPL
Image
where innovation meets technology
This is great, thank you so much!

I will check to see if it works for me soon. I'm sure if it's working for you, there's no reason it wouldn't be working. But I'll let you know if I have any questions.
7 posts Page 1 of 1