codeigniter session issue - some session info not sticking - session

I'm using codeigniter session library to hold data that is used in a series of 3 pages and I'm experiencing strange behavior. My session variables remain in tact but the values disapear. Even stranger: I'm trying to store a serialized array in my session data and the first item of the array ends up being stored in a different variable?
I've attached a link that starts at the first page in the series where it is possible to click to the next page. I've printed the user_session data at the top of both pages (the third page isn't set up yet).
http://playmatics.com/nypl/site/index.php/member_area/quest/accept_quest/12
Sessions work everywhere else, for example I'm using a session to store login data and that works fine.
I've attached my controller and view below
//CONTROLLER:
function accept_quest() {
$assoc_quest_id = end($this->uri->segments);
if(!isset($quest_id)) {
redirect('member_area/quest');
//SEND A MESSAGE: NO QUEST STARTED
}
$quest_rows = $this->quest_model->get_quest_with_images($assoc_quest_id);
$quest = current($quest_rows);
$images = $this->pull_out_images($quest_rows);
//the data array is used both in the session,
//to pass values over to the next function in the quest chain
//and in the template
$data = array();
$data['quest_id'] = $assoc_quest_id;
$data['instruction_text'] = $quest->instructions;
$data['quest_title'] = $quest->name;
$data['quest_time_limit'] = $quest->time_limit;
$data['points_awarded'] = $quest->points_availible;
$data['quest_images'] = serialize($images);
//save data in a flash session to be used in the next function call in the quest chain: quest_action
$this->session->set_userdata($data);
print_r($this->session->all_userdata());
//the following data aren't needed in the session so they are added to the data array after the session has been set
$data['annotation_text'] = $quest->note;
$data['main_content'] = 'quests/quest_desc';
$this->load->view('includes/template', $data);
}
function quest_action() {
print_r($this->session->all_userdata());
$quest_id = $this->session->userdata('quest_id');
echo "the quest id is: $quest_id";
if(!isset($quest_id)) {
redirect('member_area/quest');
//SEND A MESSAGE: NO QUEST STARTED
}
$data['quest_id'] = $quest_id;
$data['quest_title'] = $this->session->userdata('quest_title');
$data['quest_images'] = $this->session->userdata('images');
$data['instruction_text'] = $this->session->userdata('instructions');
$data['quest_time_limit'] = $this->session->userdata('quest_time_limit');
$data['main_content'] = 'quests/quest_action';
$this->load->view('includes/template', $data);
}
//VIEW
//quest_desc:
<h1><?= $quest_title ?></h1>
<div id="quest_elements">
<figure>
<? foreach(unserialize($quest_images) as $image): ?>
<img class="media" src="<?= $image ?>" alt="<?= $quest_title ?> image"/>
<? endforeach; ?>
<figcaption>annotation: <?= $annotation_text ?></figcaption>
</figure>
<?= anchor("member_area/quest/quest_action", "Start Quest", array('title' => 'start quest')); ?>
</div><!-- end quest_elements -->
//quest_action:
<h1><?= $quest_title ?></h1>
<div id="quest_elements">
<figure>
<? foreach(unserialize($quest_images) as $image): ?>
<img class="media" src="<?= $image ?>" alt="<?= $quest_title ?> image"/>
<? endforeach; ?>
<figcaption>instructions: <?= $instruction_text ?></figcaption>
</figure>
<div id="timer">
<?= $quest_time_limit; ?>
</div>
<?= anchor("#start_timer", "Start Timer", array('title' => 'start quest timer')); ?>
</div>

If you are hitting the cookie size limit, I would suggest switching to CodeIgniter's native Database Sessions class. This enables you to store session information in a database, effectively removing the cookie size limitation, you are simply restricted to the size of the user_data field in the ci_sessions database.
Following the link above, the section on utilizing database sessions is near the bottom, providing you the proper DB schema and the config switch to database sessions.

As others have said, it is likely that you are hitting the 4k cookie limit of CI's session library. There are other alternative libraries available that use standard PHP sessions - http://codeigniter.com/wiki/PHPSession/ and http://codeigniter.com/wiki/Native_session/ for instance.

Related

Setting pagination

controllers/home.php
$this->page_model->counter($this->data['post_detail']->post_ID);
$this->data['post_list'] = $this->post_model->post($this->data['post_detail']->post_ID);
$this->data['gallery_list'] = $this->post_model->post($this->data['post_detail']->post_ID, true);
$isAjax = array('news-post');
if (in_array($this->data['post_detail']->template_name, $isAjax))
{
if ( ! $this->input->is_ajax_request())
redirect($this->data['page_detail']->post_alias);
return $this->load->view($this->data['post_detail']->template_name, $this->data);
}
$this->load->view($this->data['post_detail']->template_name, $this->data);
views/news.php
<?php
$this->load->library('pagination');
$config['base_url'] = 'http://gsa-constructionspecialist.com/articles/article';
$config['total_rows'] = 14;
$config['per_page'] = 5;
$this->pagination->initialize($config);
?>
<div class="w626 content right">
<?php
if ($post_list){
foreach ($post_list as $pl){
?>
<div>
<p><br><br><strong><?php echo $pl->post_title; ?></strong></p>
<p><?php echo date('F jS, Y',strtotime($pl->post_date)); ?></p>
<br/>
<div style="text-align:justify"><?php echo word_limiter(strip_tags($pl->post_content),25); ?><span style="color:#fff"> Read More ></span></div>
</div>
<?php } } ?>
<?php echo $this->pagination->create_links(); ?>
I am trying to set the pagination but it only appears on the bottom and it does not hide the articles that suppose to be on the next page.
Please help fix the codes? Thanks in advance.
The pagination class will generate pages numbers based on the information you provide to it, however its up to you to generate the actual results for a particular page. You might tell the pagination class it's 5 results per page, but in reality it doesn't know whether you're outputting 5 results per page or 500.
It seems to me as though:
$this->data['post_list'] = $this->post_model->post($this->data['post_detail']->post_ID);
needs the current page number passing in, i.e.
$this->data['post_list'] = $this->post_model->post($this->data['post_detail']->post_ID, $current_page);
You then need to modify your database query within the model using LIMIT to limit the number of results (and the offset) for that page.
Does this help?

How to display error or success message in a template file?

I want to show message on some condition in a template file(custom module template file).I am having following code.
<?php
if(count($collection)): ?>
<?php foreach($collection as $coll): ?>
some calculations
<?php endforeach; ?>
<?php else: ?>
<?php $message = $this->__('There is no data available'); ?>
<?php echo Mage::getSingleton('core/session')->addNotice($message);?>
<?php endif;?>
But this is not working properly. The message is displayed on other pages not on the same page.
If you really need to implement that right in the template, you may use the code below:
<?php echo $this->getLayout()->createBlock('core/messages')->addNotice('My Message')->toHtml(); ?>
But the solution described by Amit Bera sounds like a better way to resolve it.
Muk,According to your code
Mage::getSingleton('core/session')->addNotice($message);
add an notice to magento.This is code set notice to session and which is reflecting on page refresh according php session ,a session variable set value is reflecting after page refresh.
If you already added this notice on other page before came to your file then ,you need to add core/session to custom module template file controllers file.
Code is $this->_initLayoutMessages('core/session');
In controller you need below code in controller.
/* load the layout from xml */
$this->loadLayout();
$this->_initLayoutMessages('core/session');
/* rendering layout */
$this->renderLayout();
Read more at inchoo blog
I found that $this->loadLayout() is what reads and clears messages from the session, therefore if you add messages before calling $this->loadLayout() then those messages should be displayed on the current page.
Example:
public function chooseFileAction() {
// a quick and dirty way to find the larger out of post_max_size and upload_max_filesize
$post_max_size = ini_get('post_max_size'); $post_max_size_int = str_replace('K', '000', str_replace('M', '000000', str_replace('G', '000000000', $post_max_size)));
$upload_max_filesize = ini_get('upload_max_filesize'); $upload_max_filesize_int = str_replace('K', '000', str_replace('M', '000000', str_replace('G', '000000000', $upload_max_filesize)));
$maxsize = $post_max_size_int < $upload_max_filesize_int ? $post_max_size : $upload_max_filesize;
// display max file size to user in a message box
$msg = 'Max file size: ' . $maxsize;
Mage::getSingleton('core/session')->addNotice($msg);
$this->loadLayout();
$this->_title($this->__('Catalog'))->_title($this->__('File Upload'));
$this->_setActiveMenu('catalog/customfileupload');
$block = $this->getLayout()->createBlock('customfileupload/adminhtml_customfileupload_choosefile');
$this->_addContent($block);
$this->renderLayout();
}
Caveat: this is tested in Magento 1.9, not 1.7.

Update multilingual content with AJAX in Yii

Refer to my code below, when user click on en button, the content will be changed to English, while clicking tw button, the content will be changed to Chinese.
However, the page will be refreshed each time when user click either en or tw button. I want to ask how can I implement AJAX content update in this case?
The result is when user click either en or tw button, the page won't be refreshed to change the content language.
Thanks
I have refer to Yii docs here, but seem that it is not appropriate for my case
C:\wamp\www\website\protected\views\site\index.php
<?php
$lang = isset($_GET["lang"]) ? $_GET["lang"] : "en_uk";
$lang = $lang == "en" ? "en_uk" : "zh_tw";
Yii::app()->setLanguage($lang);
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get">
<input type="submit" value="en" name="lang" />
<input type="submit" value="tw" name="lang" />
</form>
<div class="main">
<?php echo Yii::t(Yii::app()->controller->id, "Causeway Bay"); ?>
</div>
Best practice is to reload the page in these cases, because usually you have to update so much, that it is just not worth it.
That said, CHtml's ajaxSubmitButton is the cleanest way to implement this, because you can map every event of your call very easily. It looks something like this:
<?php
echo CHtml::ajaxSubmitButton('en', CHtml::normalizeUrl(array('site/changeLanguage')),
array(
'error'=>'js:function(){
alert("error");
}',
//if you add a return false in this, it will not submit.
'beforeSend'=>'js:function(){
alert("beforeSend");
}',
'success'=>'js:function(data){
alert("success, data from server: "+data);
}',
'complete'=>'js:function(){
alert("complete");
}',
//'update'=>'#where_to_put_the_response',
)
);
?>
You don't have to use every parameter of course. The update parameter can update a HTML tag instantly.
EDIT:
This can be done easily if you use the controller's renderPartial method, for instance in your site controller if you have the action responsible for the index.
public function actionIndex(){
//get variables, etc
if(Yii::app()->request->isAjaxRequest) {
$lang = $_POST['nameOfSubmit'];
}else {
//...
}
//if the 3rd parameter is true, the method returns the generated HTML to a variable
$page = $this->renderPartial('_page', array(/*parameters*/ ), true);
echo $page;
}
And then, in your view file you can simply have
<?php echo CHtml::ajaxSubmitButton('en', CHtml::normalizeUrl(array('site/index')),
array('update'=>'#content_div',));?>
and
<?php echo CHtml::ajaxSubmitButton('tw', CHtml::normalizeUrl(array('site/index')),
array('update'=>'#content_div',));?>

Retrieve product custom media image label in magento

I have a custom block loading products on my front page that loads the four newest products that have a custom product picture attribute set via:
$_helper = $this->helper('catalog/output');
$_productCollection = Mage::getModel("catalog/product")->getCollection();
$_productCollection->addAttributeToSelect('*');
$_productCollection->addAttributeToFilter("image_feature_front_right", array("notnull" => 1));
$_productCollection->addAttributeToFilter("image_feature_front_right", array("neq" => 'no_selection'));
$_productCollection->addAttributeToSort('updated_at', 'DESC');
$_productCollection->setPageSize(4);
What I am trying to do is grab the image_feature_front_right label as set in the back-end, but have been unable to do so. Here is my code for displaying the products on the front end:
<?php foreach($_productCollection as $_product) : ?>
<div class="fll frontSale">
<div class="productImageWrap">
<img src="<?php echo $this->helper('catalog/image')->init($_product, 'image_feature_front_right')->directResize(230,315,4) ?>" />
</div>
<div class="salesItemInfo">
<p class="caps"><?php echo $this->htmlEscape($_product->getName());?></p>
<p class="nocaps"><?php echo $this->getImageLabel($_product, 'image_feature_front_right') ?></p>
</div>
</div>
I read that $this->getImageLabel($_product, 'image_feature_front_right') was the way to do it, but produces nothing. What am I doing wrong?
Thanks!
Tre
It seems you asked this same question in another thread, so to help others who might be searching for an answer, I'll anser it here as well:
I imagine this is some sort of magento bug. The issue seems to be that the Magento core is not setting the custom_image_label attribute. Whereas for the default built-in images [image, small_image, thumbnail_image] it does set these attributes - so you could do something like:
$_product->getData('small_image_label');
If you look at Mage_Catalog_Block_Product_Abstract::getImageLabel() it just appends '_label' to the $mediaAttributeCode that you pass in as the 2nd param and calls $_product->getData().
If you call $_product->getData('media_gallery'); you'll see the custom image label is available. It's just nested in an array. So use this function:
function getImageLabel($_product, $key) {
$gallery = $_product->getData('media_gallery');
$file = $_product->getData($key);
if ($file && $gallery && array_key_exists('images', $gallery)) {
foreach ($gallery['images'] as $image) {
if ($image['file'] == $file)
return $image['label'];
}
}
return '';
}
It'd be prudent to extend the Magento core code (Ideally Mage_Catalog_Block_Product_Abstract, but I don't think Magento lets you override Abstract classes), but if you need a quick hack - just stick this function in your phtml file then call:
<?php echo getImageLabel($_product, 'image_feature_front_right')?>
Your custom block would need to inherit from Mage_Catalog_Block_Product_Abstract to give access to that method.
You could also use the code directly from the method in the template:
$label = $_product->getData('image_feature_front_right');
if (empty($label)) {
$label = $_product->getName();
}

codeigniter simplepie

I wanted to mention, i have simplepie working in my development environment but as soon as I uploaded the site I cannot get feeds into my homepage. Any ideas? here is the code that works on localhost:
function Homepage()
{
parent::Controller();
$this->base = $this->config->item('base_url');
$this->css = $this->config->item('css');
$this->images = $this->config->item('images');
$this->load->library('simplepie');
$this->simplepie->set_feed_url('http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/world/rss.xml');
$this->simplepie->set_cache_location(APPPATH.'cache/rss');
$this->simplepie->init();
$this->simplepie->handle_content_type();
}
function index()
{
$data['rssdata'] = array(
"title" => $this->simplepie->get_title(),
"description" => $this->simplepie->get_description(),
"items" => $this->simplepie->get_items(0,5)
);
$this->load->view($data)
}
this is the code that is in the view:
<h3 class="ui-widget-header"><?= $rssdata['title']?></h3>
<div id="accordion" >
<div>
<h5><?= $rssdata['description']?></h5>
<p><?php foreach($rssdata['items'] as $item) :?>
<ul>
<li><?php anchor($item->get_link(),$item->get_title());?></li>
<li class="rssfeed"><?php echo $item->get_description();?></li>
</ul>
<p><small>Posted on <?php echo $item->get_date('j F Y g:i a');?></small></p>
<?php endforeach;?>
</div>
Use the newest "bleeding edge" from their GitHub profile, it sorts out several problems with PHP 5.3 which were making Apache explode from too many errors.
At time of writing, the bleeding edge is marked as v1.2.1-dev.
I've had this problem once, when my hosting setup did not have cURL installed, and error_reporting was off....
try setting var $force_fsockopen = false; to var $force_fsockopen = true; in the SimplePie config file to see if it makes a difference

Resources