I am trying to use sessions in my CakePHP 2.3 application. When I add this to my View:
$this->Session->write('key','value');
I get the following error:
Warning (512): Method SessionHelper::write does not exist [CORE\Cake\View\Helper.php, line 179]
I have tried adding this to my controller:
var $helpers = array('Html', 'Form', 'Js'=>array("Jquery"),"Session");
public $components = array('RequestHandler','Session');
But the error still occurs. Anyone know what is going on?
thanks
From the documentation:
The major difference between the Session Helper and the Session Component is that the helper does not have the ability to write to the session.
and so there is no write() method available in the SessionHelper (which you can also see in the API).
Try changing
var $helpers = array('Html', 'Form', 'Js'=>array("Jquery"),"Session");
to
public $helpers = array('Html', 'Form', 'Js'=>array("Jquery"),"Session");
Also, I would recommend doing all session writing login in the controller, not in the view. The view is intended just to display things. So avoid it if you can.
Related
In my CodeIgniter 2 controller I call a model method which returns a ReactPHP promise, and I want to load a CodeIgniter view in the function called by that promise's ->then() method. How can I do this? What happens instead is the controller method returns nothing, so I get a blank page in the browser.
Here is a simplified example illustrating what I'm trying to do:
class My_class extends My_Controller {
function my_method() {
$this->my_model->returns_a_promise()->then(function ($data) {
// How can I pass the promise's resolved value to the template here?
// It seems this never gets called, because my_method() returns
// before we get here. :(
$this->load->view('my_view', $data);
});
}
}
Is there any way to tell the controller method not to send output to the browser until after the promise has resolved?
I'm not sure what are you trying to do but if you want to stop view from outputting and return it as a string then output it with echo yourself you can do this:
$view = this->load->view('my_view', $data, TRUE);
Now you have the view as a var string you can use it to do what you are trying to do.
It turns out the code in my original question does work. So the question is the answer. But the reason it wasn't working for me was that returns_a_promise() was not returning a resolved promise, so ->then() was not called and the view was not rendered. In order to make it return a resolved promise, I had to call $deferred->resolve(); in the code that returned the promise.
The upshot of this is that this code example demonstrates it is possible to run asynchronous PHP (via ReactPHP in this case) in CodeIgniter controller methods. My particular use case is to run many database queries concurrently in the CodeIgniter model.
try this:
function my_method() {
$data = array();
$data['promise'] =$this->my_model->returns_a_promise();
$data['view'] = 'my_view';
$this->load->view('my_view', $data);
}
I am trying to reopen same page on Codeigniter. See code below:
<?php
class Leads extends CI_Controller
{
public $tempName;
public $tempFrom;
public $tempTo;
public function index() {
$this->load->model('Lead');
$leads = $this->Lead->getAllLeads();
$pageNum = count($leads);
$this->load->view('main', array('leads' => $leads, 'pageNum' => $pageNum));
}
public function getLeads(){
$this->load->model('Lead');
$name = $this->input->post('name');
$from = $this->input->post('from');
$to = $this->input->post('to');
$leads = $this->Lead->getLeads($name, $from, $to);
$pageNum = count($leads);
$this->load->view('main', array('leads' => $leads, 'pageNum' => $pageNum));
}
}
?>
As you can see, first I open 'main' from 'index()'. In main, I call 'getLeads()', but my page is not getting updated. Is it because I can't refresh data while on the same page? If yes, how can I work around it?
Thanks a lot!
You cannot call a controller from a view. It sounds like you probably should be using AJAX in your "main" view to get additional data from getLeads().
Option A:
redirect with js to the same function you have, but change the method to get (send params in the URL and get them on the server with $this->input->get()).
Option B:
Since you are posting to getLeads I assume you are using ajax. And since you are using ajax, you should return an url or data to render on your website. Maybe you could use $this->session->set_flashdata('leads',$leads) and $this->session->set_flashdata('pageNum',$pageNum) , send an url to another controller function, extract leads and pageNum $this->session->flashdata('leads') & $this->session->flashdata('pageNum') and then render the view?
Responding with load view will not automatically set the html to what you get.
I'm using Symfony2 and I have a ReaderBundle that has an Rss entity.
I'm created CRUD for this entity.
php app/console generate:doctrine:crud --entity=RSSReaderBundle:Rss --format=annotation --with-write
All was well, before I connected Cache.
$loader = require_once __DIR__.'/../app/bootstrap.php.cache';
require_once __DIR__.'/../app/AppCache.php';
require_once __DIR__.'/../app/AppKernel.php';
Debug::enable();
$kernel = new AppKernel('dev' , true);
$kernel->loadClassCache();
$kernel = new AppCache($kernel); // THAT STRING IS MAIN PROBLEM
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
And then when i'm trying to delete some record, i take this error:
No route found for "POST /rss/delete/30": Method Not Allowed (Allow: DELETE)
405 Method Not Allowed
I created a form that clearly indicates the method:
private function createDeleteForm($id)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('rss_delete', array('id' => $id)))
->setMethod("DELETE")
->add('submit', 'submit', array('label' => 'Delete'))
->getForm()
;
}
I have not found the problem. Help please
This problem occurred since symfony2.2, see https://github.com/symfony/symfony-standard/commit/1970b831f8843a5cf551e9d88404cb62f21b90f9
You need to modify the Symfony\Component\HttpFoundation\Request::$httpMethodParameterOverride boolean manually in your app.php file:
// When using the HttpCache, you need to call the method in your front controller instead of relying on the configuration parameter
Request::enableHttpMethodParameterOverride();
There is no method="DELETE" in html forms ... at least not supported in almost all browsers - only in ajax requests.
Work around this by allowing DELETE and POST requests to the route.
we must remove the string with comment "THAT STRING IS MAIN PROBLEM". Cache is working all the same. And CRUD working right
I have the same problem that you had (with PUT and DELETE HTTP method) but I don't understand your solution.
Did you:
a) just get rid of // THAT STRING IS MAIN PROBLEM
or
b) get rid of $kernel = new AppCache($kernel); // THAT STRING IS MAIN PROBLEM
The solution b) is the same as not using cache so in my case, it's not helping as the page take a very long time to load.
#Nifr:
I thought there were method PUT and DELETE. I use them in my forms following the instructions on this link: http://symfony.com/fr/doc/current/cookbook/routing/method_parameters.html
So in fact, Symfony2 is able to tell whether a method is PUT, DELETE, POST or GET. But somehow, the cache can't...
Any help on that?
Edit:
I found a solution that doesn't involve changing anything in the app.php file.
Basically, the problem comes from the fact that the getMethod method of the request object of symfony2 doesn't know about PUT or DELETE method. The point is to change that in the AppCache.php file.
We just have to override the method invalidate of the AppCache.php file:
protected function invalidate(Request $request, $catch = false)
{
$request->setMethod($request->request->get('_method'));
return parent::invalidate($request, $catch);
}
Here, I just change the method of the request by the method posted from the form.
I'm trying to execute a Shell from my Controller via AJAX request.
In my controller :
public function log_import() {
$this->autoRender = false;
App::import('Console/Command', 'AppShell');
App::import('Console/Command', 'IzigetlogShell');
$job = new IzigetlogShell();
$job->dispatchMethod('main');
echo "REPONSE";
}
And my shell :
<?php
App::import('Core', 'Controller');
App::import('Controller', 'Suivis');
class IzilogShell extends AppShell {
public $uses = array('Suivi');
-- DU CODE --
$this->Suivi = new SuivisController();
$this->Suivi->constructClasses();
$exist_date = $this->Suivi->find('first',
array(
'conditions' => array('Suivi.date' => $date_calcul)
));
}
But i always get the same error message :
PHP Fatal error: Call to undefined method SuivisController::find() in C:\wamp\www\iziboxLogs\app\Console\Command\IzigetlogShell.php on line XX
I tried to execute the shell from the console and i got the same error.
Any ideas ? Thanks, Martin
The short answer is: You don't!
Its a violation of the MVC what cake stands for.
You need to move your "shared" code into a model and use this model only in both cases. not the controller (which is the link/logic from model and "webbrowser", not your shell). and not the shell from within the controller (since the shell is the link/logic from model and "CLI").
So:
Model contains all the code
Shell uses Model and its methods
Controller uses Model and its method
=> DRY and clean
then you would also need not a single App::import (or better App::uses) statement.
PS: if you happen to have a lot of non-model code, you can also make a Lib in APP/Lib and use this as your common class.
PPS: public $uses = array('Suivi'); is for models anyway, not for controllers (as the docs speficy by the way).
By doing this
$this->Suivi = new SuivisController();
this->Suivi becomes a SuiviController and not a Suivi model anymore.
But you then use it as a model:
$exist_date = $this->Suivi->find(...);
The find() method is a model method, not a controller method. So if you do need to call the find() method, there is no need to instanciate the SuivisController at all.
I want to convert a URL which is of the format
path/to/my/app/Controller_action/id/2
to
path/to/my/app/Controller_action/id/User_corresponding_to_id_2
I have already seen this tutorial from Yii, but it isnt helping me with anything. Can anyone help me with this?
EDIT: I would also like to know if this thing is even possible in the POST scenario, ie I will only have path/to/my/app/Controller_action in the URL.
Add a getUrl method in your User model
public function getUrl()
{
return Yii::app()->createUrl('controller/action', array(
'id'=>$this->id,
'username'=>$this->username,
));
}
Add the following rule urlManager component in config/main.php
'controller/action/<username:.*?>/<id: \d+>'=>'controller/action'
And use the models url virtual attribute everywhere
dInGd0nG is on the correct track, but if I understand correctly you wish to do actions based on the actual username instead of the ID as well right?
It's not that hard in Yii. I'm assuming here for simplicity the controller is user and the action is view.
Your User controller:
public function actionView($id)
{
if (is_numeric($id))
$oUser = User::model()->findByPk($id);
else
// Luckily Yii does parameter binding, wouldn't be such a good idea otherwise :)
$oUser = User::model()->findByAttributes(array('username' => $id));
...
}
Your urlManager config:
'user/view/<id: \w+>' => 'user/view',
Or more generally:
'user/<action: \w+>/<id: \w+> => 'user/<action>',
To generate a user url in a view:
$this->createUrl('user/view', array('id' => $oUser->username));