header("refresh:5; url='pagetoredirect.php'");
we can use this if we want to redirect our page in 5 second ,
is there any way to redirect page in 5 second in cakephp ?
if yes please let me know
You could try with AppController header() method:
http://api.cakephp.org/class/app-controller#method-AppControllerheader
In your controller:
class CarController{
public function add(){
$this->header("") //Implemented on AppController::header
}
}
/cake/libs/controller/controller.php
/**
* Convenience and object wrapper method for header(). Useful when doing tests and
* asserting that particular headers have been set.
*
* #param string $status The header message that is being set.
* #return void
* #access public
*/
function header($status) {
header($status);
}
...
Which shows that the Controller::header( ) function is a simple wrapper for direct calls to the php function header( ).
http://api.cakephp.org/class/app-controller#method-AppControllerheader
So - to accomplish what you want to do:
/app/controllers/examples_controller.php
<?php
class ExamplesController extends AppController
{
public $name = "Examples";
...
public function someAction( ){
...
$url = array( 'controller' => 'examples', 'action' => 'someOtherAction' );
$this->set( 'url', $url );
$this->header( "refresh:5; url='".Router::url( $url )."'" );
}
...
}
?>
I pass the url to the view and don't die( ) or exit( ) in case you actually wish to render a view. An example:
/app/views/examples/some_action.ctp
<p class='notice'>
<?php echo $this->Html->link( "You are being redirected to ".Router::url( $url )." in 5 seconds. If you do not wish to wait click here.", $url ); ?>
</p>
Do not use $this->header in controller as it will be removed in 3.0. Use CakeResponse::header().
here is working example for cakephp 2.8
Controller:
$url = array('controller' => 'pages', 'action' => 'index');
$second = '5';
if (!$sessionData) {
return $this->redirect($url);
}
$this->Session->delete($bookingStr);
$this->response->header("refresh:$second; url='" . Router::url($url) . "'");
$this->set(compact('url', 'second'));
View:
<p class='notice'>
<?php echo $this->Html->link( "You are being redirected to ".Router::url($url, TRUE)." in ".$second." seconds. If you do not wish to wait click here.", $url ); ?>
</p>
<div class="step-content">
<div class="booking-form">
<div class="row">
Thank you.
</div>
</div>
</div>
Related
in controller
public function home($id=null){
$this->loadModel('Usermgmt.User');
if(isset($id)){
$groups=$this->User->findAllByuser_group_id($id);
$this->set('groups', $groups);
} else{
echo 'no id';
$users=$this->User->find('all');
$this->set('users', $users);
}
}
here i geeting value which matches the user_group_id and prints here i am geeting more then 10 users but i need to print only 5 on one page and need to give pagination how to give pagination here
view
<?php
if (!empty($groups)) {
// print_r($groups);
$sl=0;
foreach ($groups as $row1) {
//print_r($row1);
$sl++; ?>
<div style="width:100%;display:inline-block;">
<div style="float:left">
<?php
//echo $row1['id'];
echo $this->Html->link($this->Html->image('../files/user/photo/'.$row1 ['User']['photo_dir'].'/'.$row1 ['User']['photo'], array('width' => '180', 'height' => '180')),
array('controller'=>'Profiles','action'=>'index',$row1['User']['id']),
array('escape' => false));
?>
</div>
<div>
<?php echo h($row1['User']['first_name'])." ".h($row1['User']['last_name'])."</br>";
echo h($row1['User']['username'])."</br>";
echo h($row1['User']['email'])."</br>";
echo h($row1['User']['mobile'])."</br>";
echo h($row1['UserGroup']['name'])."</br>";
?></div>
<div style="clear:both;"></div>
</div>
<?php }
}?>
Call paginate
The equivalent paginate call to this:
$groups=$this->User->findAllByuser_group_id($id);
(incidentally - that should be findAllByUserGroupId) is this:
$groups = $this->paginate('User', array('user_group_id' => $id));
Changing default options
To achieve:
i need to print only 5 on one page
Modify the paginate property of your controller, e.g.:
class UsersController extends AppController {
public $paginate = array('limit' => 5);
function home($id = null) {
...
$conditions = array();
if ($id) {
$conditions['user_group_id'] = $id;
}
$groups = $this->paginate('User', $conditions);
...
}
}
View Modifications
In your view, the pagination helper, and the pagination information will automatically be available by calling paginate as shown above. To get pagination links use the pagination helper:
echo $this->Paginator->numbers();
See the documentation for more information and examples of using pagination.
As in cakephp pagination can be done using pagination helper of cakephp
In controller action use $this->paginate . From Model return all parameters like fields, conditions and so on in array format , so now in controller you will write
$data = $this->ModelName->functionname();
$currentPage = isset($_REQUEST['currentpage']) ? $_REQUEST['currentpage'] : '';
$this->paginate = array(
'fields' => $data['fields'],
'conditions' => $data['conditions'],
'order' => $data['order'],
'page' => $currentPage,
'limit' => 25
);
$currentPage is fetched from $_REQUEST['currentpage'];
and finally pass this data to Paginate Helper
$data = $this->paginate('ModelName');
Now in view you will use Pagination functions as shown below
<?php echo $this->Paginator->prev('revious'); ?>
<?php echo $this->Paginator->numbers(); ?>
<?php echo $this->Paginator->next('Next'); ?>
I have to use a form once in footer and in individual page i.e. index.ctp.
For that I have a database table named contactforms.
I have created a model Contactform.php
<?php
App::uses('AppModel', 'Model');
/**
* Contactform Model
*
*/
class Contactform extends AppModel {
/**
* Validation rules
*
* #var array
*/
var $useTable = false;
public $validate = array(
'firstname' => array(
'notempty' => array(
'rule' => array('notempty')
)
),
'contactno' => array(
'notempty' => array(
'rule' => array('notempty')
)
),
'email' => array(
'notempty' => array(
'rule' => array('notempty')
)
)
);
}
?>
I have a controller from where I am trying to send an email
<?php
App::uses('AppController', 'Controller');
App::uses('CakeEmail', 'Network/Email');
class ContactformsController extends AppController {
public function index() {
$this->Contactform->recursive = 0;
$this->set('contactforms', $this->paginate());
}
public function contact() {
$email = new CakeEmail();
if(isset($this->params['requested']) && $this->params['requested']==true)
{
if ($this->request->is('post'))
{
$this->Contactform->set($this->request->data);
if($this->Contactform->save($this->request->data))
{
$name=$this->request->data['Contactform']['firstname'];
$lastname=$this->request->data['Contactform']['lastname'];
$contact=$this->request->data['Contactform']['contactno'];
$mail= $this->request->data['Contactform']['email'];
$email->from(array($mail => $name));
$email->to('abc#gmail.com');
$message= $this->request->data['Contactform']['message'];
$email->subject('Wombats contact form information');
if($email->send($message))
{
$this->Session->setFlash('Quote Processed..Thank You For Visiting Our Website!!!');
$this->redirect($this->referer());
}
}
}
}
}
}
?>
And then I created an element which I used called in footer and then in index file.
contact.ctp looks like
<?php echo $this->Html->css('contactfooter.css');?>
<?php $contactforms = $this->requestAction('Contactforms/contact') ?>
<div class="frm">
<?php echo $this->Form->create('Contactform'); ?>
<div class="firstrow">
<div class="first">
<?php echo $this->Form->input('firstname',array('label'=>false,'placeholder'=>'firstname','div'=>'firstname','style'=>'width:130px; height:20px;' ));?>
<?php // echo $this->Form->input('firstname',array('label'=>false,'placeholder'=>'firstname','style'=>'width:130px; height:20px; float:left; margin-right:5px;','error'=>array('attributes'=>array('wrap'=>'div','class'=>'errorfirst'))));?>
</div>
<div class="second">
<?php echo $this->Form->input('lastname',array('label'=>false,'placeholder'=>'lastname','div'=>'lastname','style'=>'width:140px; height:20px; '));?>
</div>
</div>
<!--<div class="secondrow">-->
<?php echo $this->Form->input('contactno',array('label'=>false,'placeholder'=>'contactno','div'=>'contactno','style'=>'width:270px; height:20px; margin-bottom:10px;'));?>
<!--</div>-->
<?php echo $this->Form->input('email',array('label'=>false,'placeholder'=>'email','div'=>'email','style'=>'width:270px; height:20px; '));?>
<?php echo $this->Form->input('message',array('label'=>false,'placeholder'=>'message','div'=>'message','style'=>'width:270px; height:25px;margin-top:10px; '));?>
</div>
<!--<br>-->
<div class="sub">
<?php echo $this->Form->end('SUBMIT'); ?>
</div>
When I click submit of one form other form as well validates.
I tried a lot but don't know how to fix Can anyone please help.
EDIT:-
#Nunser I am very confused with these names sorry for that. I have changed my code according to what u told but still its validating one form only.
I have a doubt, according to you I should change in view and elements too but I just have elements.Please can u help I am posting my edited code
I called element from index page as
<?php echo $this->element('Contactform/contact',array('source'=>'index')); ?>\
and from default page as
<?php echo $this->element('Contactform/contact'); ?>
my controller action is
public function contact() {
$email = new CakeEmail();
if(isset($this->params['requested']) && $this->params['requested']==true){
if ($this->request->is('post'))
{
$index = 'Contactform';
if (isset($this->request->data['Contactformindex']))
$index = 'Contactformindex';
$this->Contactform->set($this->request->data[$index]);
if($this->Contactform->save($this->request->data[$index]))
{
$name=$this->request->data[$index]['firstname'];
$lastname=$this->request->data[$index]['lastname'];
$contact=$this->request->data[$index]['contactno'];
$mail= $this->request->data[$index]['email'];
$email->from(array($mail => $name));
$email->to('skyhi13#gmail.com');
$message= $this->request->data[$index]['message'];
$email->subject('Wombats contact form information');
//$email->send($message);
if($email->send($message))
{
$this->Session->setFlash('Quote Processed..Thank You For Visiting Our Website!!!');
//$this->render('/view/elements/quotes/quoteform.ctp');
// $this->autoRender=FALSE;
$this->redirect($this->referer());
}
}
else {
$this->set('formName',$index);
}
}
}
}
In the elements ctp file I changed as
<?php if (!empty($this->validationErrors['Contactform'])) {
$this->validationErrors[$formName] = $this->validationErrors['Contactform'];
}?>
<div class="frm">
<?php
if(isset($source)&& $source == 'index')
echo $this->Form->create('Contactformindex');
else
echo $this->Form->create('Contactform');
?>
<div class="firstrow">
<div class="first">
<?php echo $this->Form->input('firstname',array('label'=>false,'placeholder'=>'firstname','div'=>'firstname','style'=>'width:130px; height:20px;' ));?>
<?php // echo $this->Form->input('firstname',array('label'=>false,'placeholder'=>'firstname','style'=>'width:130px; height:20px; float:left; margin-right:5px;','error'=>array('attributes'=>array('wrap'=>'div','class'=>'errorfirst'))));?>
</div>
<div class="second">
<?php echo $this->Form->input('lastname',array('label'=>false,'placeholder'=>'lastname','div'=>'lastname','style'=>'width:140px; height:20px; '));?>
</div>
</div>
<!--<div class="secondrow">-->
<?php echo $this->Form->input('contactno',array('label'=>false,'placeholder'=>'contactno','div'=>'contactno','style'=>'width:270px; height:20px; margin-bottom:10px;'));?>
<!--</div>-->
<?php echo $this->Form->input('email',array('label'=>false,'placeholder'=>'email','div'=>'email','style'=>'width:270px; height:20px; '));?>
<?php echo $this->Form->input('message',array('label'=>false,'placeholder'=>'message','div'=>'message','style'=>'width:270px; height:25px;margin-top:10px; '));?>
</div>
<!--<br>-->
<div class="sub">
<?php echo $this->Form->end('SUBMIT'); ?>
</div>
Using this code still it validated one form only and form is that which I have called without source as index and when clicked on index submit button it validates the other form. I am not sure as do I have to use the same Fromindex name as specified by you, does that matter. I am not able to find as where I am going wrong.Please help and Thanks in advance.
First, why are you doing this
<?php $contactforms = $this->requestAction('Contactforms/contact') ?>
in your element? I don't see the use of that requestAction except slowing down the processing...
Ok, but your problem...
Since you're calling an element, there's no easy way to avoid the validation of both forms. Usually, when there are two forms corresponding to the same model, the way to not validate both is to change the "name" of the form like this
<!--in the first form-->
<?php echo $this->Form->create('Contactform1'); ?>
<!--in the second form-->
<?php echo $this->Form->create('Contactform2'); ?>
But, since you are creating that form with an element, there's no easy way of changing the name of the form in one place and not in the other...
So this is what you should do (there may be other ways of doing what you want, but this is the one I can think of). When you call the contact.ctp element, pass a variable to it
echo $this->element('contact', array(
"source" => "index"
));
With that, you know you're calling the element from the index.ctp, for example. Then, in the element, change the form declaration depending on the variable
//the beginning of your element
<?php
if (isset($source) && $source == 'index')
echo $this->Form->create('FromIndex');
else
echo $this->Form->create('FromContact');
?>
You'll also need to modify your action, to read the data in FromIndex or in FromContact, depending on where it came from
public function contact() {
$email = new CakeEmail();
if(isset($this->params['requested']) && $this->params['requested']==true) {
if ($this->request->is('post')) {
//change the index of the array depending on where it came form
$index = 'FromContact';
if (isset($this->request->data['FromIndex']))
$index = 'FromIndex';
$this->Contactform->set($this->request->data[$index]);
if($this->Contactform->save($this->request->data[$index]))
{
$name=$this->request->data[$index]['firstname'];
$lastname=$this->request->data[$index]['lastname'];
$contact=$this->request->data[$index]['contactno'];
$mail= $this->request->data[$index]['email'];
$email->from(array($mail => $name));
$email->to('abc#gmail.com');
$message= $this->request->data[$index]['message'];
$email->subject('Wombats contact form information');
if($email->send($message))
{
$this->Session->setFlash('Quote Processed..Thank You For Visiting Our Website!!!');
$this->redirect($this->referer());
}
}
}
}
}
}
When you save or set something (unless is with saveAssociated, saveAll or those kind of functions, when you're saving more than one model), there's no need to specify the model in the array to be saved.
$saveMe = array('User'=>array('name'=>'John'));
$saveMeToo = array('name'=>'John');
$this->User->save($saveMe); //will work
$this->User->save($saveMeToo); //will work too
That's why the change of $this->request->data indexes will work either way. But the validation will be for the specific index (FromContact or FromIndex).
Note: I haven't tested the code, so be sure to check for missing parenthesis, unclosed ' and those kind of things.
EDiT
#winnie pointed out that the validation only happened for one form, and that's because I overlooked something. The validation errors get displayed in the view if there's something set in this variable $this->validationErrors['ModelName'] in the view. And that's what I missed. So, re-change the action to pass the $index of the model to the view, so the view knows which form called the action, like this
public function contact() {
$email = new CakeEmail();
if(isset($this->params['requested']) && $this->params['requested']==true) {
if ($this->request->is('post')) {
//change the index of the array depending on where it came form
$index = 'FromContact';
if (isset($this->request->data['FromIndex']))
$index = 'FromIndex';
$this->Contactform->set($this->request->data[$index]);
if($this->Contactform->save($this->request->data[$index]))
{
//this if is exactly the same as the other one
} else {
//now, if there's no save, there's some validation errors
//tell the view which form called this save
$this->set('formName', $index);
}
}
}
Now in the view you need to copy the errors you get in the model, to the "fake model name" we gave the form. In the first line of your view do this (and in the element too)
if (!empty($this->validationErrors['Contactform'])) {
$this->validationErrors[$formName] = $this->validationErrors['Contactform'];
}
I am trying to add pagination in CakePHP 2.x with condition search in a form. However, in the View it doesn't give the next page with my condition. Here is my code:
Controller
public function result($palabraclave = null)
{
$this->layout = 'tempart';
$this->paginate = array(
'limit' => 5,
'order' => array(
'Articulo.created' => 'desc'),
'conditions'=>array("titulo like ?"=>"%".$this->data['Paginas']['palabraclave']."%")
)
$data = $this->paginate('Articulo');//Consulta a la base de datos
$this->set(compact('data'));
}
If I click "next" to see the next page result of the search, it doesn't pass on the pagination condition from page 1 to page 2. :(
View:
<div style="display: inline-block; width:70%;" id="test">
<?php foreach ($data as $da): ?>
<br />
<article>
<?php echo $this->Html->image('article_preview/mini_'.$da['Articulo']['imagen'], array('alt' => 'Hospital-Excel'))?>
<div style="text-align:left;">
<?php echo $this->Html->link("<h6 class='artnombre'>".$da['Articulo']['titulo']."<h6>", array('class'=>"artnombre",'action'=> 'articulo',$da['Articulo']['id']),array('escape' => false)); ?>
</div>
<br />
<p>
<?php echo $da['Articulo']['descripcion']; ?> <?php echo $this->Html->link('Read more ....', array('action'=> 'articulo',$da['Articulo']['id'])); ?>
<h5></h5>
</p>
<div class="puntoshorizontal" style="clear"></div>
</article>
<?php endforeach; ?>
<div style="text-align:center">
<?php
// Shows the page numbers
// Shows the next and previous links
echo $this->Paginator->prev('« Back', null, null, array('class' => 'disabled')) . " |";
echo $this->Paginator->numbers(). "| ";
echo $this->Paginator->next('Next »', null, null, array('class' => 'disabled'));
echo "<br />";
echo $this->Paginator->counter();
// prints X of Y, where X is current page and Y is number of pages
?>
</div>
</div>
a way to persist your search params on each page you should do the following:
After you post data, in your method you have $this->data['Paginas']['palabraClave'] then save it the the session. So in each subsequent call to /resultados/pag1,2,..n you get the value of palabra clave from the session.
Finally you would get something like:
public function resultados(){
$conditions = array();
if($this->Session->check('conditions')){
$conditions = $this->Session->read('conditions');
}
if(isset($this->data)){
$conditions = array("titulo LIKE" => "%".this->data['Paginas']'palabraclave']"%",));
//save to the session
$this->Session->write('conditions',$conditions);
}
$data = $this->painate('Articulo',$conditions);
$this->set('data');
}
This may need some adjust but the idea I think is clear.
Set your paginate conditions when calling the paginate method, like this:
$data = $this->paginate('Articulo', array(
"titulo LIKE" => "%" . $this->data['Paginas']['palabraclave'] . "%",
));
as opposed to in the paginate property.
this is example:
1: pass all URL arguments to paginator functions
$this->Paginator->options(array('url' => $this->passedArgs));
2: Common mistake: not keep condition search with paginate
if($this->data){
$this->passedArgs = array(
'name' => $this->data[‘User’]['name']
);
}else{
if(isset($this->passedArgs['name'])){
$this->data[‘User’]['name'] = $this->passedArgs['name'];
}else{
$this->data[‘User’]['name'] = ;
}
}
I am trying to finish this website in cake php that was previously in regular php, but as newbie in the cakephp world.. I have found some difficulties such as these.
1) .When I click on login, it transfers me to another page although i have specified no redirects in app controller except when there is a registration. The login is at the top and its viewable through out all the pages, but if i click login, it redirects me to the login page (which i do not want).
2.) After I login, it brings in the session with the user name saying welcome 'username' but then if I go to another page, it seems like it forgets the session and brings back the inputs for the login form at the top of the page.
Here is my code
app_controller
<?php
class AppController extends Controller {
var $helpers = array('Html', 'Form', 'Javascript', 'Session');
var $components = array('Auth', 'Session');
function beforeFilter() {
$this->Auth->allow('add','get_categories','get_home', 'get_others', 'pages');
$this->Auth->autoRedirect = false;
}
}
?>
UsersController
<?php
class UsersController extends AppController {
var $uses = array("User");
var $components = array('Auth', 'Session');
function index()
{
$this->set('users', $this->User->find('all'));
$this->layout = 'master_layout';
}
function add() {
if (!empty($this->data)) {
//pass is hashed already
//->data['User']['password'] = $this->Auth->password($this->data['User']['password']);
if ($this->User->save($this->data)) {
$this->Session->setFlash('Your were registered!.');
$this->redirect(array('action' => 'get_home'));
}
}
$this->layout = 'master_layout';
}
//IF THE DATABASE IS SET UP CORRECTLY CAKE AUTHENTICATES AUTOMATICALLY NO
//LOGIC IS NEEDED FOR LOGIN http://book.cakephp.org/view/1250/Authentication
function login() {
$this->layout = 'master_layout';
if ($this->data) {
if ($this->Auth->login($this->data)) {
// Retrieve user data
$results = $this->User->find(array('User.username' => $this->data['User']['username']), array('User.active'), null, false);
$this->redirect(array('controller' => 'users', 'action' => 'login'));
}
}
$this->data['User']['password'] = '';
}
function logout() {
$this->redirect($this->Auth->logout());
}
}
?>
elements/loginform.ctp
<?php
if ($this->Session->read('Auth.User.username')):?>
<?php
echo "Welcome".' ' ;
echo $this->Session->read('Auth.User.username');
echo " ";
echo $html->link('logout', array('action'=>'logout'));
?>
<?php else : ?>
<div class="types form">
<?php echo $form->create('User', array('controller' => 'Users','action' => 'login')); ?>
<?php echo $form->input('username', array('label' => 'username')); ?>
<?php echo $form->input('password',array('type'=>'password', 'label' => 'password')) ?>
<?php echo $form->submit('Submit'); ?>
</div>
<?php endif; ?>
UPDATE
I added the following to the app_controller
<?php
class AppController extends Controller {
var $helpers = array('Html', 'Form', 'Javascript', 'Session');
var $components = array('Auth', 'Session');
function beforeFilter() {
//new addition
$this->set('userData', $this->Session->read());
$this->Auth->allow('add','get_categories','get_home', 'get_others', 'pages', '*');
$this->Auth->autoRedirect = false;
}
}
?>
WHEN I LOGIN I GET THIS ARRAY
Array ( [Config] => Array
( [userAgent] => 8f12200c2d48fa7955465842befe1c9e
[time] => 1323562284 [timeout] => 10 )
[Auth] => Array (
[User] => Array (
[id] => 63
[user_role] => 2 [
[user_fname] => test
[user_lname] => test
[user_email] => test#test.com
[user_phone] => 677-988-7777
[user_cellphone] => 555-456-9999
[user_address1] => 1st Avenue
[user_address2] =>
[user_city] => Citiland FL
[user_zip] => 55555
[username] => admin2 ) ) )
BUT WHEN I NAVIGATE TO A NEW PAGE
Array ( [Config] => Array (
[userAgent] => 8f12200c2d48fa7955465842befe1c9e
[time] => 1323562591 [timeout] => 10 ) )
ADDED PRINT_R TO elements/loginform TO SEE THE VARIABLE CONTENTS ACROSS ALL PAGES
<?php
print_r($userData);
if ($this->Session->read('Auth.User.username')):?>
<?php
echo "Welcome".' ' ;
echo $this->Session->read('Auth.User.username');
echo " ";
echo $html->link('logout', array('action'=>'logout'));
?>
<?php else : ?>
<div class="types form">
<?php echo $form->create('User', array('controller' => 'Users','action' => 'login')); ?>
<?php echo $form->input('username', array('label' => 'username')); ?>
<?php echo $form->input('password',array('type'=>'password', 'label' => 'password')) ?>
<?php echo $form->submit('Submit'); ?>
</div>
<?php endif; ?>
1) This is because in your UsersController you have a redirect after the user is logged in.
Your login function should instead read:
function login() {
$this->layout = 'master_layout';
if ($this->data) {
if ($this->Auth->login($this->data)) {
// Retrieve user data
$results = $this->User->find(array('User.username' => $this->data['User']['username']), array('User.active'), null, false);
/*This is the offending line, I've commented it out, but you could have it redirect somewhere else (it might be a good idea to redirect to the index action, for example, or just delete it:*/
//$this->redirect(array('controller' => 'users', 'action' => 'login'));
}
}
$this->data['User']['password'] = '';
}
As for 2), I believe it may be because you are not setting the data afterwards, so that while it exists in a tmp directory on the server (using the Session component) it is not actually being passed along to the view. So basically I think it's because you can't call Session methods in the view. Even if I'm not entirely correct about that, what I'm suggesting to do should work: Instead of calling session methods in the view, call them in the controller, set them in a variable for the view to access using $this->set();, then test against that variable in the view.
If you need to do this for ton of views and actions, you could consider adding something like this to your controller or even your app controller:
function beforeFilter() {
// Get session data for appllication use
$this->appuserstuff = $this->Session->read();
}
function beforeRender() {
// Make app variables available to view
$this->set('userData', $this->appuserstuff);
}
Alternatively, if you just need this in a couple actions, you could just set the user data in those actions with a:
$this->set('userData', $this->Session->read());
Now I'd recommend that you do a <?php debug($userData); ?> in one of your views so you can see how the data is structured in the array when it is set, so that you can user or test conditionals against. Finally, you could replace the direct calls to Session in your view with instead checks against the array of data:
Please note that I'm not sure how your specific array is structured so do a debug as recommended above and plug in your own keys for it to work:
<?php
if (!empty($userData['User'])):?>
<?php
echo "Welcome".' ' ;
echo $userData['User']['username'];
echo " ";
echo $html->link('logout', array('action'=>'logout'));
?>
<?php else : ?>
<div class="types form">
<?php echo $form->create('User', array('controller' => 'Users','action' => 'login')); ?>
<?php echo $form->input('username', array('label' => 'username')); ?>
<?php echo $form->input('password',array('type'=>'password', 'label' => 'password')) ?>
<?php echo $form->submit('Submit'); ?>
</div>
<?php endif; ?>
I have no idea how to handle these two separate paginations in the same view. Thanks for helping.
Controller code:
[...]
$this->Post->bindModel(array(
'hasAndBelongsToMany'=>array('Tag'),
'belongsTo'=>array('User')),false);
if($this->Session->check('Auth.User.id'))
$this->Post->bindModel(array(
'hasMany'=>array(
'UserVote'=>array('conditions'=>array('UserVote.user_id'=>$this->Session->read('Auth.User.id') )),
'Favorite'=>array('conditions'=>array('Favorite.user_id'=>$this->Session->read('Auth.User.id') ))
)), false);
$posts = $this->paginate($this->Post,array('Post.public'=>1,'Post.user_id'=>$uid));
$posts2 = $this->paginate($this->Post,array('Post.public'=>0,'Post.user_id'=>$uid));
$this->set('posts',$posts);
$this->set('posts2',$posts2);
[...]
Even though in most cases a right solution would be to rearchitect your UI to remove the need for double pagination, the following is a working solution:
First, in your controller you override Cake's paginate() function to look for paginator key:
/**
* Handles automatic pagination of model records.
*
* #param mixed $object Model to paginate (e.g: model instance, or 'Model', or 'Model.InnerModel')
* #param mixed $scope Conditions to use while paginating
* #param array $whitelist List of allowed options for paging
* #return array Model query results
* #access public
* #link http://book.cakephp.org/view/165/Controller-Setup
*/
function paginate($object = null, $scope = array(), $whitelist = array(), $key = null) {
$results = parent::paginate($object, $scope, $whitelist);
if ($key) {
$this->params['paging'][$key] = $this->params['paging'][$object];
unset($this->params['paging'][$object]);
}
return $results;
}
Then
/**
* undocumented function
*
* #param string $key
* #return void
* #access public
*/
function _pageForPagination($by) {
$page = 1;
$samekey = isset($this->params['named']['by']) && $this->params['named']['by'] == $by;
$pageInUrl = isset($this->params['named']['page']);
if ($samekey && $pageInUrl) {
$page = $this->params['named']['page'];
}
$this->passedArgs['page'] = $page;
return $page;
}
/**
* FIXME: Wrapper for Cake's pagination
* Change pagination criteria on the fly (conditions, grouping, order, limit)
*
* #param string $model
* #param string $criteria
* #return void
* #author Andrew
*/
function _paginateBy($key) {
$this->User->unbindModel(array('hasMany' => array('UserImage')), false);
$this->paginate['User'] = am($this->User->getCriteria($key), array('page' => $this->_pageForPagination($key)));
return $this->paginate('User', array(), array(), $key);
}
Then use it like so in the controller:
$this->set('byJoinDate', $this->_paginateBy('random'));
In the model:
echo $paginator->prev('prev', array('model' => $by, 'class' => 'back'), null, array('model' => $by, 'class' => 'disabled back'));
I recently had to do this very thing because I had a single HTML page that had tabs on it and in each tab was a different paginated table of the same model with different conditions for each.
The way I worked around the problem was to create dummy models that derived from the model I wanted to paginate multiple times. Then I simply referenced those dummy models for my pagination.
Example:
Base Model
class Post extends appmodel { };
Dummy Models - it is important that they use the same table as the base model
class Posts1 extends Post { var $useTable = 'posts'; }
class Posts2 extends Post { var $useTable = 'posts'; }
In your controller
function multiview($id = null) {
$this->paginate['Posts1'] = array(
'conditions'=>array('Posts1.field'=>0),
'limit'=>5
);
$this->set('posts1', $this->paginate('Posts1'));
$this->paginate['Posts2'] = array(
'conditions'=>array('Posts2.field'=>1),
'limit'=>5
);
$this->set('posts2', $this->paginate('Posts2'));
}
Then in your view
Display first paginated data
<?php foreach ($posts1 as $post): ?>
Do Paginated row display here...
<?php endforeach; ?>
<!-- Shows the page numbers -->
<?php echo $this->Paginator->numbers(array('model'=>'Posts1')); ?>
<!-- Shows the next and previous links -->
<?php echo $this->Paginator->prev('« Previous', null, null, array('class' => 'disabled')); ?>
<?php echo $this->Paginator->next('Next »', null, null, array('class' => 'disabled')); ?>
<!-- prints X of Y, where X is current page and Y is number of pages -->
<?php echo $this->Paginator->counter(); ?>
Display second paginated data
<?php foreach ($posts2 as $post): ?>
Do Paginated row display here...
<?php endforeach; ?>
<!-- Shows the page numbers -->
<?php echo $this->Paginator->numbers(array('model'=>'Posts2')); ?>
<!-- Shows the next and previous links -->
<?php echo $this->Paginator->prev('« Previous', null, null, array('class' => 'disabled')); ?>
<?php echo $this->Paginator->next('Next »', null, null, array('class' => 'disabled')); ?>
<!-- prints X of Y, where X is current page and Y is number of pages -->
<?php echo $this->Paginator->counter(); ?>
As the Pagination helper relies on the $controller->pagination field I think this is impossible. A quick hack would be to convert one or both of the paginations to Ajax-based ones. The pagination helper works very well with the Ajax helper.
Is it a good idea to have two separate paginations on a page? It looks like You're trying to paginate through public posts and non-public posts - which surely can't be done at the same time? I.e. the user won't ever be on page 3 of the public posts and page 2 of the non-public posts at the same time. The only case this would really work is via AJAX with the pagination occouring in page as suggested by matiasf.
Would it not be a better solution to just show the first x public and non public posts in the current view and create a new view to show the pagination for each accessed by a link e.g. "view all public posts" and "view all non public posts"?