CakePHP - Saving one session variable deletes another - php

I'm using session variables in CakePHP to store my relevant user Twitter and Facebook data, when the user logs in if he has linked his Twitter and FB accounts this information is saved in the session variable next to my own user data.
I have a screen where the user can link and unlink said social network data, the problem is the following:
Let's say I have both networks connected, I decide to disconnect from Facebook, the session variable for Facebook is deleted. Now I wish to reconnect to Facebook, I click on the Connect button, the Facebook data is saved but for some reason it deletes the Twitter variable.
The way my process works is the following:
1) User clicks on connect button.
2) User is directed to social network auth.
3) User is directed to a function that takes the required data, saves it in a session variable called NetworkData and is directed back to the page where he clicked the button.
4) The NetworkData is extracted, set as the according social network (Facebook or Twitter) in the session and is deleted from the session.
Code is as follows:
This is the function that the user is directed after login in to Twitter or FB:
function retrieve_network($page) {
$networkData = null;
$this->autoRender = false;
$this->layout = 'ajax';
if(isset($_GET['oauth_token'])) {
$token = $this->TwitterHelper->setOAuthToken($_GET['oauth_token']);
$userinfo = $this->TwitterHelper->getTwitterUserInfo();
$networkData = array(
'TwitterData' => array(
'username' => $userinfo['username'],
'name' => $userinfo['name'],
'token' => $token->oauth_token,
'token_secret' => $token->oauth_token_secret
)
);
} else if (isset($_GET['code'])) {
$token = $this->FacebookHelper->facebook->getAccessToken();
$userinfo = $this->FacebookHelper->getUserInfo();
$networkData = array(
'FacebookData' => array(
'username' => $userinfo['username'],
'name' => $userinfo['name'],
'email' => $userinfo['email'],
'token' => $token,
'link' => $userinfo['link'],
)
);
}
$this->Session->write('NetworkData', $networkData);
if($page == 'settings') {
$this->redirect(array('controller' => 'fonykers', 'action' => 'settings/networks'));
}
}
This is the function that retrieves what's in network data and sets it to the session:
function settings($tab) {
$this->layout = 'frontend';
$this->Fonyker->recursive = -1;
$this->TwitterData->recursive = -1;
$this->FacebookData->recursive = -1;
if(!$this->checkSessionCookie()) {
$this->redirect(array('controller' => 'pages', 'action' => 'home'));
}
$fields = array(
'Fonyker.id',
'Fonyker.username',
'Fonyker.name',
'Fonyker.email',
'Fonyker.gender',
'Fonyker.birthdate',
'Fonyker.image_url'
);
$fonyker = $this->Fonyker->find('first', array(
'conditions' => array(
'Fonyker.fonykid' => $this->Session->read('Fonyker.Fonyker.fonykid')
),
'fields' => $fields
));
$this->Fonyker->set($fonyker);
$this->data = $fonyker;
if($this->Session->read('NetworkData')) {
$networkData = $this->Session->read('NetworkData');
$this->Session->delete('NetworkData');
if($networkData['TwitterData']) {
$networkData['TwitterData']['fonyker_id'] = $fonyker['Fonyker']['id'];
if($this->TwitterData->save($networkData)) {
$this->Session->write('TwitterData', $networkData['TwitterData']);
}
} else if($networkData['FacebookData']) {
$networkData['FacebookData']['fonyker_id'] = $fonyker['Fonyker']['id'];
if($this->FacebookData->save($networkData)) {
$this->Session->write('FacebookData', $networkData['FacebookData']);
}
}
}
pr($this->Session->read());
if(!$this->Session->read('TwitterData')) {
$this->TwitterHelper->setTwitterObj();
$this->set('twitterUrl', $this->TwitterHelper->twitterObj->getAuthorizeUrl(null, array('oauth_callback' => 'http://127.0.0.1/fonykweb/pages/retrieve_network/settings')));
} else {
$this->set('twitterUrl', '#');
}
if(!$this->Session->read('FacebookData')) {
$this->set('facebookUrl', $this->FacebookHelper->facebook->getLoginUrl(array('redirect_uri' => 'http://localhost/fonykweb/pages/retrieve_network/settings','scope' => 'email,user_birthday,publish_stream,offline_access')));
} else {
$this->set('facebookUrl', '#');
}
$this->set('tab', $tab);
}
This is the function that removes the network if the user wishes:
function remove_network($network) {
$this->autoRender = false;
$this->Fonyker->recursive = -1;
$this->TwitterData->recursive = -1;
$this->FacebookData->recursive = -1;
$response = null;
if($network == 'twitter') {
$twitterData = $this->TwitterData->find('first', array(
'conditions' => array(
'TwitterData.fonyker_id' => $this->Session->read('TwitterData.fonyker_id')
)
));
if($this->TwitterData->delete($twitterData['TwitterData']['id'], false)) {
$this->TwitterHelper->setTwitterObj();
$twitterUrl = $this->TwitterHelper->twitterObj->getAuthorizeUrl(null, array('oauth_callback' => 'http://127.0.0.1/fonykweb/pages/retrieve_network/settings'));
$this->Session->delete('TwitterData');
$response = json_encode(array('ok' => true, 'url' => $twitterUrl));
} else {
$response = json_encode(array('ok' => false));
}
}
if($network == 'facebook') {
$facebookData = $this->FacebookData->find('first', array(
'conditions' => array(
'FacebookData.fonyker_id' => $this->Session->read('FacebookData.fonyker_id')
)
));
if($this->FacebookData->delete($facebookData['FacebookData']['id'], false)) {
$facebookUrl = $this->FacebookHelper->facebook->getLoginUrl(array('redirect_uri' => 'http://localhost/fonykweb/pages/retrieve_network/settings','scope' => 'email,user_birthday,publish_stream,offline_access'));
$this->Session->delete('FacebookData');
$response = json_encode(array('ok' => true, 'url' => $facebookUrl));
} else {
$response = json_encode(array('ok' => false));
}
}
echo $response;
}
View code:
<script type="text/javascript">
$(document).ready(function() {
var splitUrl = window.location.href.split('/');
$('#' + splitUrl[splitUrl.length - 1] + '-tab').addClass('active-tab');
$('#' + splitUrl[splitUrl.length - 1] + '-tab').children().addClass('active-tab');
});
</script>
<div class="prepend-1 prepend-top span-23">
<div class="tabs span-22">
<ul>
<li id="account-tab">
<a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/account">
Account
</a>
</li>
<li id="password-tab">
<a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/password">
Password
</a>
</li>
<li id="notifications-tab">
<a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/notifications">
Notifications
</a>
</li>
<li id="networks-tab">
<a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/networks">
Social Networks
</a>
</li>
</ul>
</div>
<div class="tab-content prepend-top prepend-1">
<?php
if($tab == 'account') {
echo $this->element('settings/account');
} else if ($tab == 'password') {
echo $this->element('settings/password');
} else if ($tab == 'notifications') {
echo $this->element('settings/notifications');
} else {
echo $this->element('settings/networks');
}
?>
</div>
</div>
Element code:
<script type="text/javascript">
$(document).ready(function(){
var deleteNetwork = function(network, button) {
$.ajax({
url: '<?php echo $html->url('/fonykers/remove_network/', true); ?>' + network,
dataType: 'json',
type: 'POST',
success: function(response) {
if(response.ok) {
button.replaceWith('<a id="'+network+'-connect" class="connect-button connect" href="'+response.url+'" class="span-3">Connect</a>');
}
}
});
}
if($('#twitter-connect').attr('href') == '#'){
$('#twitter-connect').addClass('connected');
$('#twitter-connect').html('Connected');
} else {
$('#twitter-connect').addClass('connect');
$('#twitter-connect').html('Connect');
}
if($('#facebook-connect').attr('href') == '#'){
$('#facebook-connect').addClass('connected');
$('#facebook-connect').html('Connected');
} else {
$('#facebook-connect').addClass('connect');
$('#facebook-connect').html('Connect');
}
$('.connected').hover(
function() {
$(this).removeClass('connected');
$(this).addClass('disconnect');
$(this).html('Disconnect')
},
function() {
$(this).removeClass('disconnect');
$(this).addClass('connected');
$(this).html('Connected')
}
);
$('#twitter-connect').click(function(event) {
if($(this).attr('href') == '#') {
event.preventDefault();
deleteNetwork('twitter', $(this));
}
});
$('#facebook-connect').click(function(event) {
if($(this).attr('href') == '#') {
event.preventDefault();
deleteNetwork('facebook', $(this));
}
});
});
</script>
<div class="span-4 prepend-top">
<div class="span-4">
<div class="span-1">
<?php echo $html->image('twitter-connect.png', array('alt' => 'Twitter', 'class' => 'span-1', 'style' => 'height:40px;width:40px')); ?>
</div>
<div class="span-3 last">
<a id="twitter-connect" class="connect-button" href="<?php echo $twitterUrl; ?>" class="span-3"></a>
</div>
</div>
<div class="span-4 prepend-top">
<div class="span-1">
<?php echo $html->image('facebook-connect.png', array('alt' => 'Twitter', 'class' => 'span-1', 'style' => 'height:40px;width:40px')); ?>
</div>
<div class="span-3 last">
<a id="facebook-connect" class="connect-button" href="<?php echo $facebookUrl; ?>"></a>
</div>
</div>
</div>
Sorry for the long post.

In your retrieve_network action, which I am assuming you call when a user reconnects to a particular service, you are overwriting the NetworkData session variable
if you find 1 particular Service has been connected to:
if(isset($_GET['oauth_token'])) {...}
OR
if(isset($_GET['code'])) {...}
You set $networkData to the returned services object and then overwrite the whole session via:
$this->Session->write('NetworkData', $networkData);
Following your code, I would always check to see if an existing service is currently in session and if so do not overwrite the whole session, just add the particular data to the existing NetworkData session array:
if($this->Session->read('NetworkData.TwitterData')){
$facebookData = array(
'username' => $userinfo['username'],
'name' => $userinfo['name'],
'email' => $userinfo['email'],
'token' => $token,
'link' => $userinfo['link'],
);
$this->Session->write('NetworkData.FacebookData', $facebookData);
}
Note: This is just an example showing how you can achieve this. I would refactor that method with better logic for this particular situation, perhaps storing TwitterData and FacebookData in their own separate arrays as opposed to a larger more complex NetworkData array. Additionally, you can access $_GET params via $this->params['url']['paramname'] to maintain cakePHP convention.

I think the issue is that you are replacing network data, instead of merging it.
This means that when you login with FB for example, you replace any twitter data with FB, instead of keeping them both.
I'm hoping that maybe instead of
$this->Session->write('NetworkData', $networkData);
that
$this->Session->write('NetworkData', array_merge($networkData, $this->Session->read('NetworkData'));
might work.
Otherwise, it seems to me the session deleting code shouldn't be interacting for one to delete the other. I could have missed something in skimming it though. I'd do some echo()ing / debugging to follow the code execution paths.

Related

Wordpress theme fatal error "Fatal error: Call to undefined method WP_Error::get_items()"

One of my Wordpress themes is showing the following error:
Fatal error: Call to undefined method WP_Error::get_items() in /home1/mywebsite/public_html/learnphp123.com/wp-content/themes/econews/admin/IDE_admin.php on line 88
The code for the file is (you can see "get_items()" on line 88 .... actually the third line in the code):
if($feed) {
$html = '<ul>';
foreach ($feed->get_items() as $item){
$html.="<li><span>".$item->get_date('d M Y')."</span> ".$item->get_title()."</li>";
}
Can anybody tell me what to use in the place of "get_items()"?
Thank you very much for your help!
The total code of the file is given below and I am only getting the error on line 88 related to feed get_items ().
<?php
/*
Copyright 2010, idesigneco.com
http://idesigneco.com
*/
define('IDE_ADMIN_FEED', 'http://idesigneco.com/wp_pub.php?id=ide_admin_newsfeed.xml&theme='.IDE_CODE.'&ver='.IDE_VERSION);
// load form generator and validator
include IDE_ADMIN_PATH.'IDE_FormGenerator.class.php';
// initialize the admin form
$Form = new IDE_FormGenerator(array(
'name' => 'admin',
'method' => 'post',
'action' => ''
));
// setup the form fields
$Form->elements(
null,
array(
'admin_action' => array(
'type' => 'hidden', 'value' => 'admin',
'error' => 'Your settings have been updated.'
)
)
);
// load theme specific options
include IDE_ADMIN_PATH.'/IDE_admin_options.php';
$Form->elements(
null,
array(
'submit' => array(
'type' => 'submit', 'value' => 'Save', 'label' => ''
),
)
);
$Form->printErrors(true);
// ________________________________________________________
// process the form data
if(!empty($_POST['admin_action'])) {
// unchecked checkbox options don't show up, so fill them with predefined key names
ide_save_options( array_merge( array_fill_keys($IDE_checkboxes, ''),
stripslashes_deep($_POST)
)
);
$Form->setErrors(array('admin_action'));
}
// ________________________________________________________
// populate the form with saved options
$Form->data($IDE_options);
// ________________________________________________________
// print out the admin area
ide_admin_header();
$Form->generate();
ide_admin_footer();
// ________________________________________________________
// idesigneco news feed
function ide_admin_news() {
$time = ide_option('admin_newsfeed_time');
$html = ide_option('admin_newsfeed');
// feed expired, update
if(!$html || !$time || ($time+(5*3600)) < time() ) {
if(function_exists('fetch_feed')){
$feed = fetch_feed(IDE_ADMIN_FEED);
if($feed) {
$html = '<ul>';
foreach ($feed->get_items() as $item){
$html.="<li><span>".$item->get_date('d M Y')."</span> ".$item->get_title()."</li>";
}
$html.= '</ul>';
} else {
$html = 'Updates unavailable at this time';
}
} else {
// deprecated feed api
if(function_exists('fetch_rss')){
include_once(ABSPATH . WPINC . '/rss.php');
$rss = fetch_rss(IDE_ADMIN_FEED);
$html = '<ul>';
foreach ($rss->items as $item){
$html.="<li><span>".date('d M Y', strtotime($item['pubdate']))."</span> ".$item['title']."</li>";
}
$html.= '</ul>';
}
}
ide_save_option('admin_newsfeed_time', time());
ide_save_option('admin_newsfeed', $html);
}
echo $html;
}
// admin header
function ide_admin_header() {
?>
<div id="ide_admin">
<div class="left">
<h1 class="ide_title"><?php echo IDE_NAME.' '.IDE_VERSION; ?></h1>
<div class="clear"> </div>
<?php
}
// admin footer
function ide_admin_footer() {
?>
</div><!-- left //-->
<div class="right">
<div class="idesigneco">
<img src="<?php echo IDE_ADMIN_STATIC.'/idesigneco.png'; ?>" alt="Theme by iDesignEco" title="Theme by iDesignEco" />
</div>
<div class="news">
<h2>iDesignEco Updates</h2>
<?php ide_admin_news(); ?>
</div>
</div><!-- right //-->
<div class="clear"> </div>
</div><!-- ide_admin //-->
<?php
}
?>
This probably happens when getting data for $feed fails, so it becomes WP_Error class that does not have get_items() method. Try to modify the code like this:
if (! is_wp_error( $feed )) {
$html = '<ul>';
foreach ($feed->get_items() as $item){
$html.="<li><span>".$item->get_date('d M Y')."</span> ".$item->get_title()."</li>";
}
UPDATE:
Just as I assumed, the $feed gets its data from fetch_feed(), so the solution should still be to replace:
if($feed) {
with:
if (! is_wp_error( $feed )) {

Cakephp 2.X disable/enable syntax

I'm using the following example
http://jsfiddle.net/nc6NW/1/
Yet when I change this to formhelper syntax the Jquery does not re-enable the disabled save functionality. How does one remove this attribute given this function
<div id="newArticleForm">
<?php
echo $this->Form->create('Post', array('action' => 'add'));
echo $this->Form->input('article_title',array('type' => 'text', 'id'=>'ArticleHeader','div'=>false,'label'=>false,'class'=>'centertext',"placeholder"=>"Article Header"));
echo $this->Html->para(null,'<br>', array());
echo $this->Form->input('article_link',array('type' => 'text', 'id'=>'ArticleLink','div'=>false,'label'=>false,'class'=>'centertext',"placeholder"=>"Article Link"));
echo $this->Html->para(null,'<br>', array());
echo $this->Form->button('Cancel', array('type' => 'reset'), array('inline' => false));
echo $this->Form->button('Save', array('type' => 'submit', 'disabled'=>true), array('inline' => false));
echo $this->Form->end();
?>
</div>
<script>
$(':text').keyup(function() {
if($('#ArticleHeader').val() != "" && $('#ArticleLink').val() != "") {
$('#submit').removeAttr('disabled');
} else {
$('#submit').attr('disabled', true);
}
});
</script>
Solved it, sorry for wasting everyone's time
submit had the wrong identifier, needed a colon not a hash.
i.e.
$(':text').keyup(function() {
if($('#ArticleHeader').val() != "" && $('#ArticleLink').val() != "") {
$(':submit').removeAttr('disabled');
} else {
$(':submit').attr('disabled', true);
}
});

PHP code to upload multiple files with database

I have issue with multiple file upload in cakephp.
I try to upload multiple files and need to insert multiple entries in table, but I am unable to do this.
For Ex - if I upload 3 photos from form then need to be inserted 3 rows in table with their file name.
public function add() {
$this->Driver->create();
if ($this->request->is('post')) {
for($i=1;$i<4;$i++)
{
if(empty($this->data['Driver']['document'.$i]['name'])){
unset($this->request->data['Driver']['document'.$i]);
}
if(!empty($this->data['Driver']['document'.$i]['name']))
{
$file=$this->data['Driver']['document'.$i];
$ary_ext=array('jpg','jpeg','xls','docx'); //array of allowed extensions
$ext = substr(strtolower(strrchr($file['name'], '.')), 1); //get the extension
if(in_array($ext, $ary_ext))
{
move_uploaded_file($file['tmp_name'], APP . 'outsidefiles' .DS. time().$file['name']);
$this->request->data['Driver']['document'.$i] = time().$file['name'];
}
}
}
if ($this->Driver->save($this->request->data))
{
//echo "<pre>";print_r($this->request->data); exit();
$this->Session->setFlash('Your post has been saved.');
$this->redirect(array('action' => 'add'));
}
else
{
$this->Session->setFlash('Unable to add your post.');
}
}
}
add.ctp
<h1>Add Post</h1><?php
echo $this->Form->create('Driver', array('url' => array('action' => 'add'), 'enctype' => 'multipart/form-data'));
echo $this->Form->input('address',array('div' => false, 'class' => 'form-control user-name'));
for($i=1; $i<4; $i++)
{
?>
<div id="attachment<?php echo $i;?>" <?php if($i !=1) echo "style='display:none;'";?> >
<div>
<?php echo $this->Form->input('document'.$i,array('type'=>'file','label' => false,'div' => false));?>
</div>
<div id="attachmentlink<?php echo $i;?>" <?php if($i==3) echo "style='display:none;'";?>>Add Another Attachment</div>
</div>
<?php } ?>
<?php
echo $this->Form->end('Save');
?>
Plz try this
public function add() {
$this->Driver->create();
if ($this->request->is('post')) {
for($i=1;$i<4;$i++)
{
if(empty($this->data['Driver']['document'][$i]['name'])){
unset($this->request->data['Driver']['document'.$i]);
}
if(!empty($this->data['Driver']['document'][$i]['name']))
{
$file=$this->data['Driver']['document'][$i];
$ary_ext=array('jpg','jpeg','xls','docx'); //array of allowed extensions
$ext = substr(strtolower(strrchr($file['name'], '.')), 1); //get the extension
if(in_array($ext, $ary_ext))
{
move_uploaded_file($file['tmp_name'], APP . 'outsidefiles' .DS. time().$file['name']);
$this->request->data['Driver']['document'][$i] = time().$file['name'];
}
}
}
if ($this->Driver->save($this->request->data)){
$this->Session->setFlash('Your post has been saved.');
$this->redirect(array('action' => 'add'));
}else{
$this->Session->setFlash('Unable to add your post.');
}
}
}
CakePHP 2 Field naming conventions
echo $this->Form->input('Modelname.0.fieldname');
echo $this->Form->input('Modelname.1.fieldname');
in your view file
//for($i=1; $i<4; $i++)..
echo $this->Form->input('Driver.'.$i.'.document', array('type' => 'file'));
in your controller like
$this->request->data['Driver'][$i]['document']['name'] // where name is uploaded document filename
Use Model::saveMany(array $data = null, array $options = array())
Method used to save multiple rows of the same model at once...
if ($this->Driver->saveMany($this->request->data))...
UPDATE your code
<?php
public function add()
{
if ($this->request->is('post')) {
for($i=1;$i<4;$i++)
{
if(empty($this->request->data['Driver'][$i]['document']['name'])){
unset($this->request->data['Driver'][$i]['document']);
}
if(!empty($this->request->data['Driver'][$i]['document']['name']))
{
$time = time(); // <-------------
$file=$this->request->data['Driver'][$i]['document'];
$ary_ext=array('jpg','jpeg','xls','docx'); //array of allowed extensions
$ext = substr(strtolower(strrchr($file['name'], '.')), 1); //get the extension
if(in_array($ext, $ary_ext))
{
move_uploaded_file($file['tmp_name'], APP . 'outsidefiles' .DS. $time.$file['name']);
$this->request->data['Driver'][$i]['document'] = $time.$file['name'];
}
}
}
$this->Driver->create();
if ($this->Driver->saveMany($this->request->data))
{
//echo "<pre>";print_r($this->request->data); exit();
$this->Session->setFlash('Your post has been saved.');
$this->redirect(array('action' => 'index'));
}
else
{
$this->Session->setFlash('Unable to add your post.');
}
}
}
add.ctp
<h1>Add Post</h1>
<?php
echo $this->Form->create('Driver', array( 'type' => 'file'));
//echo $this->Form->input('address',array('div' => false, 'class' => 'form-control user-name')); ????
for($i=1; $i<4; $i++)
{
?>
<div id="attachment<?php echo $i;?>" <?php if($i !=1) echo "style='display:none;'";?> >
<div>
<?php echo $this->Form->input('Driver.'.$i.'.document',array('type'=>'file','label' => false,'div' => false));?>
</div>
<div id="attachmentlink<?php echo $i;?>" <?php if($i==3) echo "style='display:none;'";?>>Add Another Attachment</div>
</div>
<?php } ?>
<?php
echo $this->Form->end('Save');
?>

reload just a part of a page after ajax request

I am trying to add a search module for my data listing .
my function that i post the request to, renders a view.
how can i load the list grid after pushing search button?
should i echo a html code, or render a view and write that view in that position?
I am totally confused ...
public function actionSell() {
$cond="";
if($_POST) {
foreach ($_POST as $key => $value) {
$_POST[$key] = str_replace(',', '', stripslashes(mysql_real_escape_string($value)));
}
$melk_id = $_POST['melk_id'];
$city_id = $_POST['city_id'];
$cost_from = $_POST['cost_from'];
$cost_to = $_POST['cost_to'];
$metraj_from = $_POST['metraj_from'];
$metraj_to = $_POST['metraj_to'];
if($melk_id) $cond .= ' and melk_id='.$melk_id;
if($city_id) $cond .= ' and city_id='.$city_id;
if($cost_from) $cond .= ' and cost >='.$cost_from;
if($cost_to) $cond .= ' and cost <='.$cost_to;
if($metraj_from) $cond .= ' and metraj >='.$metraj_from;
if($metraj_to) $cond .= ' and metraj <='.$metraj_to;
}
$dataProvider = new CActiveDataProvider('Data', array('criteria' => array(
'condition' => 'type = 0 '.$cond,
'order' => 'id DESC',
),
'pagination' => array('pageSize' => 15)
));
$this->render('sell', array(
'dataProvider' => $dataProvider,
));
}
I'm not a php developer but I'll try yo answer in a jQuery manner.
Suppose you hold your list grid in a container: <div id="container"> //the grid </div>
You fill the container from a View that holds the grid
You have Seach TextBox
<input id="searchBox" type="text" name="SeachTxt" Value="Some text"/>
And a Button :
<input id="SearchBtn" type="button" value="Search Now!">
Next you must have a jQuery ajax post function, like this one:
jQuery("#SearchBtn").click(function(e) {
e.preventDefault();
jQuery.ajax({
url: 'index.php?searchString=' + jQuery("#searchBox").val(),
success: function(result) {
jQuery("#container").html(result);
}
});
});
you could use renderPartial, like
$this->renderPartial('_ajaxContent', array(
'dataProvider' => $dataProvider
), false, true
);

Help creating an ajax method to add to basket

I have the following code that I want to turn into a silent ajax function so the page does not need to refresh, when a user adds a product the basket.
Currently I have the following code,
PHP
function showProduct($productId)
{
if (!$productId > 0)
{
redirect('home');
}
$this->load->model('Product_model');
$this->load->model('Checkout_model');
$this->data['items'] = $this->Checkout_model->GetProducts();
// Check to see if the Add To Bag button has been clicked.
if ($this->input->post('btnAddToBag'))
{
$derivativeId = $this->input->post('selDerivative-1');
$quantity = $this->input->post('selQuantity');
$derivative = $this->Product_model->GetProducts(array('pdId' => $derivativeId), 'small');
// Add item to shopping bag.
$attributes = $this->Product_model->GetProductDerivatives(array('pdId' => $derivativeId));
$this->Checkout_model->AddProduct($derivative, $attributes, $quantity);
$this->data['message'] = 'Item added to Shopping Bag.';
// Update Delivery Price
$this->Checkout_model->updateDelivery(49);
//get the bag details
}
$this->data["product_details"] = $this->Product_model->GetProducts(array('productId' => $productId, 'pdOrdering' => 1), 'detail');
$this->data['product_images'] = $this->Product_model->GetProductImages(array('productId' => $productId, 'ipPosition' => 'detail'));
//send the new filename to the view
//die(print_r($this->data['product_images']));
//die(print_r($this->data['sliderUrl']));
// Retrieve images for initial derivative.
$this->load->model('Attribute_model');
$this->data['derivative_images'] = $this->Attribute_model->GetAttributeValues(array('pdavProductDerivativeId' => $this->data["product_details"]->pdId), 'small', TRUE);;
$derivatives = $this->Product_model->GetProductDerivatives(array('pdProductId' => $productId));
$this->data["product_derivatives"] = $derivatives['derivatives'];
$this->data["product_attribute_names"] = $derivatives['attributeNames'];
// Retrieve details of this range.
$subRangeId = $this->data["product_details"]->productRangeId;
$this->data["sub_range_details"] = $this->Range_model->GetRanges(array('range.rangeId' => $subRangeId));
$rangeId = $this->data["sub_range_details"]->rangeParentId;
$this->data['active_menu_item'] = "subrange";
if ($rangeId == 0)
{
$rangeId = $subRangeId;
$this->data['active_menu_item'] = "full";
}
$this->data["range_details"] = $this->Range_model->GetRanges(array('range.rangeId' => $rangeId, 'range.rangeParentId' => 0), 'navigation');
if ($rangeId != $subRangeId)
$this->template->set_breadcrumb($this->data["range_details"]->rangeTitle, $this->data["range_details"]->rangePath);
//$this->data["rangePath"] = $this->uri->segment(1).'/';
$this->data["rangeId"] = $rangeId;
$this->data["subRangeId"] = $subRangeId;
// Retrieve list of sub ranges in this range.
$this->data["sub_ranges"] = $this->Range_model->GetRanges(array('range.rangeParentId' => $rangeId));
$this->data["individual_products"] = $this->Product_model->GetProducts(array('psiParentId' => $productId), 'small');
$this->data["related_products"] = $this->Product_model->GetRelatedProducts(array('product_related.prProductId' => $productId, 'ordering' => 'productActualPrice'), 'small');
$this->data['bestsellers'] = $this->Product_model->GetProducts(array('productBestSeller' => '1', 'range.rangeParentId' => $rangeId, 'ordering' => 'range.rangeOrder'), 'small');
$this->data["multibuy"] = $this->Product_model->GetProducts(array('psi.psiChildId' => $productId, 'productSavingType' => 'multi-buy'));
//$this->load->view('collection', $data);
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH']=="XMLHttpRequest") {
$this->template
->build('product/quickview', $this->data); // views/product/product.php
}else{
$this->template
->set_layout('default') // application/views/layouts/default.php
->title(($this->data["product_details"]->productMetadataTitle != '' ? $this->data["product_details"]->productMetadataTitle : $this->data["product_details"]->productTitle))
->set_metadata('keywords', $this->data["product_details"]->productMetadataKeywords, 'meta')
->set_metadata('description', ($this->data["product_details"]->productMetadataDescription != '' ? $this->data["product_details"]->productMetadataDescription : $this->data["product_details"]->productShortDesc), 'meta')
->set_metadata('', site_url('assets/js/product.js'), 'js')
->set_metadata('', site_url('assets/js/jquery.nivo.slider.js'), 'js')
->set_metadata('', site_url('assets/js/slider.js'), 'js')
->set_partial('left-nav', 'blocks/ranges_sub_menu') // application/views/blocks/ranges_sub_menu.php
->set_breadcrumb($this->data["sub_range_details"]->rangeTitle, $this->data["sub_range_details"]->fullRangePath)
->set_breadcrumb($this->data["product_details"]->productTitle, $this->data["product_details"]->fullProductPath)
->build('product/product', $this->data); // views/product/product.php
}
}
HTML FORM
<?php echo form_open(current_url(), array('id' => 'frmProducts'), array('submitted' => '1')); ?>
<div class="formRow">
<label for="rattanType"><?php echo $product_attribute_names; ?> </label><br />
<?php
$options = array();
foreach ($product_derivatives as $derivative) :
$options[$derivative['derivativeId']] = $derivative['attributeValues'];
endforeach;
?>
<?php echo form_dropdown('selDerivative-1', $options, $product_details->pdId, 'class="select clear" id="selDerivative-1"'); ?>
</div>
<?php if (count($individual_products) > 0) : ?>
<div class="formRow">
<label for="itemType">Item</label><br />
<select class="select clear" id="selURL-1" name="selURL-1">
<option value="<?php echo current_url(); ?>">Full Set</option>
<?php foreach ($individual_products as $product) : ?>
<option value="<?php echo site_url($product->fullProductPath); ?>"><?php echo $product->productTitle; ?> - £<?php echo ($product->productSavingType != 'none' ? $product->productSavingPrice : $product->productPrice); ?></option>
<?php endforeach; ?>
</select>
<input id="btnGo-1" name="btnGo-1" type="submit" value="GO" />
</div>
<?php endif; ?>
<div class="formRow">
<label for="addQty">Quantity</label><br />
<?php
$options = array();
for ($i = 1; $i < 10; $i++) :
$options[$i] = $i;
endfor;
?>
<?php echo form_dropdown('selQuantity', $options, '1', 'class="small select clear"'); ?>
</div>
<input type="submit" value="add to bag" name="btnAddToBag" id="btnAddToBag" />
<?php echo form_close(); ?>
// Reset action of form when add to bag button is clicked.
$("#btnAddToBag").click(function () {
$("#frmProducts").attr("action","<?php echo current_url(); ?>");
});
How can I change this code that it makes an ajax request and updates the cart without refreshing the page?
You need to split off your basket display into another file so that you can use:
$.load()
Example basic usage:
$('#ShoppingCart').load('Cart.php', function() {
alert('Load was performed.');
});
<div id="ShoppingCart"> </div>
Or a little more like youve currently got it set up:
$("#btnAddToBag").click(function () {
$('#ShoppingCart').load('Cart.php', function() {
alert('Load was performed.');
});
});
Edit:
Re-reading your post, do you not want the cart to update atall?
In that case you would need to use $.post()
See: http://api.jquery.com/jQuery.post/
I have already answered a question for JSP/SERVLET here this one should work by changing the URL to a PHP page...
You need to make an XML Http request to the Servlet for that you need to make a XML Http object in the javascript in your HTML/PHP page
var myxmlhttpobj=new GetXmlHttpObject();
function GetXmlHttpObject()
{
if (window.XMLHttpRequest)
{
// code for IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
}
if (window.ActiveXObject)
{
// code for IE6, IE5
return new ActiveXObject("Microsoft.XMLHTTP");
}
return null;
}
Now you need to make a request to the PHP from the javascript
var url="urlofPHPpage";
var para="parmeter1=value1&parameter2=valu2;
myxmlhttpobj.open("POST",url,true);
myxmlhttpobj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
myxmlhttpobj.setRequestHeader("Content-length", para.length);
myxmlhttpobj.setRequestHeader("Connection", "close");
myxmlhttpobj.onreadystatechange=ajaxComplete;
myxmlhttpobj.send(para);
At the PHP page you need to process the result and sent it back as string:
When the request comes back the myxmlhttpobj.onreadystatechange=ajaxComplete; will be called
function ajaxComplete(){
if(myxmlhttpobj.readyState==4){
///Display the result on the HTML/PHP Page BASKET
}
}
That should help...
Also have a look at jQuery Ajax API.

Categories