I have a form in my Plugin elements and what i would like to insert the checkbox value into a table named it_queries and field status_type and its giving me an error Undefined variable: variableValue [APP\Plugin\Feedback\View\Elements\comment_add.ctp, line 37] .I have declared the variable in my controller like this
$this->set('variableValueStatus', 'Pending');
and this is line 37 thats giving me the error
Below is the Controller code
App::uses('FeedbackAppController', 'Feedback.Controller');
class CommentsController extends FeedbackAppController
{
public $components = array('Feedback.Comments');
public function add($foreign_model = null, $foreign_id = null)
{
if (empty($foreign_model) ||
empty($foreign_id) ||
!$this->request->is('post')
)
{
foreach ($_POST['likebutton'] as $pageId => $likeFlag) {
$dbFlag = $likeFlag ? 'Yes' : 'No';
}
return $this->redirect('/');
}
App::uses($foreign_model, 'Model');
$Model = ClassRegistry::init($foreign_model);
if (!($Model instanceof Model))
{
return $this->redirect('/');
}
if ($Model->hasAny(array($Model->primaryKey => $foreign_id)) == false)
{
return $this->redirect('/');
}
if (!isset($this->request->data['Comment']['foreign_model']) ||
!isset($this->request->data['Comment']['foreign_id']) ||
$this->request->data['Comment']['foreign_model'] != $foreign_model ||
$this->request->data['Comment']['foreign_id'] != $foreign_id)
{
return $this->redirect('/');
}
$user_id = null;
if (isset($this->Auth))
{
$user_id = $this->Auth->user('id');
}
$this->request->data['Comment']['foreign_model'] = $Model->name;
$this->request->data['Comment']['foreign_id'] = $foreign_id;
$this->request->data['Comment']['user_id'] = $user_id;
$this->Comment->create();
if (!$this->Comment->save($this->request->data))
{
$this->set('validation_errors', $this->Comment->validationErrors);
return;
}
$this->redirect($this->request->referer().'#comment-'.$this->Comment->id);
}
}
and in the add view in my element here is how i am trying to accessing the variable value
echo $this->Form->checkbox('ItQuery.status_type', array('type' => 'hidden', 'value'=>$variableValueStatus));
If someone can show me how to fix this, that would be awesome
You are only passing the variable down on !post and if foreign model and foreign id are not set.
That will most likely not work in most of the cases.
You should be always passing down a variable if you do not check on it in the view prior to using it.
But it would still be wrong, anyway. You would have to use "default" instead of "value" if you dont want your form to fall back on the old value on POST (which it shouldnt).
Also, it is always better to use $this->request->data to properly fill the form with defaults:
if (!$this->request->is('post')) {
$this->request->data['ItQuery']['status_type'] = 'Pending';
}
See working-with-forms
Related
I'm trying to pass array from one controller to another. But I have no idea how to that.
I have my Bill Controller with array:
public function store(Request $request, $id,$sid)
{
$selected = array();
if ($request->annual != 0) {
$selected['annual'] = $request->annual;
}
if ($request->registration != 0) {
$selected['registration'] = $request->registration;
}
if ($request->monthly != 0) {
$selected['monthly'] = $request->monthly;
}
if ($request->annual != 0) {
$selected['annual'] = $request->annual;
}
return redirect()->route('invoice', [$sid]);
}
Here, I have passed $sid to another controller PdfController through route.
My Route:
Route::get('sid/{sid}', 'PdfController#invoice')->name('invoice');
PdfController:
class PdfController extends Controller
{
public function invoice($sid)
{
$data = $this->getData();
$date = date('Y-m-d');
$student = Student::where('id',$sid)->first();
$view = \View::make('layouts.bill',compact('data', 'date','student'))->render();
$pdf = \App::make('dompdf.wrapper');
$pdf->loadHTML($view);
return $pdf->stream('invoice');
}
How can I pass array from my BillController to my PdfController? Can anyone help me?
You can use different ways,
Create a cache (Cache::forever) variable and pass it.
Create a database temporary table with model and pass it.
Create a static variable and first set your variable and get again.
If you can tell which data you need to pass, we can help you much better.
I want that when a record is saved and marked as active, all other records are marked INactive.
I've tried the following code in my model:
public function beforeSave($options = array()) {
if (!empty($this->data['Ticket']['is_active'])) {
$this->data['Ticket']['is_active'] = 0;
}
return true;
}
However this code is error
Use afterSave
Instead of using beforeSave, it's more appropriate to use afterSave, and updateAll like so:
public function afterSave($created) {
if (!empty($this->data[$this->alias]['is_active'])) {
$this->updateAll(
array('is_active' => 0),
array(
'id !=' => $this->id,
'is_active' => 1
)
);
}
}
I.e. after successfully saving a record, if it is active disable all the others.
Note: be sure to use the same method signature as the parent class. It varies depending on which version of CakePHP you are using.
You can write before save method like
public function beforeSave($options=array()){
if (!empty($this->data[$this->alias]['is_active'])) {
$this->data[$this->alias]['is_active'] = 0;
}
return true;
}
It has come to my attention that the redirect controller method is not working part of the time. No message appears when I set debug > 0. I don't echo any code before calling the redirect method so it shouldn't be because of "headers already sent".
Let's take a look at my ArticlesController add action where redirect works in one instance but not in another.
public function add($page = null) {
// Custom component to get if user has required access level
// of page to write an article. If not, setflash to an error message
// specific to user's access level and redirect.
$access_message = $this->CustomPage->AccessMessage(4, $this->viewVars['access']);
if($access_message){
// Flash works but redirect does not
$this->Session->setFlash(__($access_message));
$this->redirect(array('action' => 'index', 'page' => $page));
// Also tried
// $this->redirect(array('controller'=>'articles', 'action' => 'index', 'page' => $page), null, true);
} else
{
if ($this->request->is('post')) {
$this->Article->create();
if ($this->Article->save($this->request->data)) {
// BLAH BLAH save post, do other stuff
// BLAH BLAH save post, do other stuff
// This flash and redirect works
$this->Session->setFlash(__('The article has been saved'));
$this->redirect(array('action' => 'view', 'id' => $article_id, 'page' => $page));
} else {
$this->Session->setFlash(__('The article could not be saved. Please, try again.'));
} // end else if article cannot be saved
} // if method is post
} // end if user has access
} // end add action
It definitely has something to do with the component but I'm not sure what. Maybe since redirect is called right after the component is used, the "$this" is trying to do the redirect method on the component instead of the controller. I tried $this->Article->redirect and reloading the Article model before the redirect but neither of those worked.
My component code is:
public function AccessMessage($required_level, $user_level) {
if(!$user_level && $this->_View->viewVars['access']){
$user_level = $this->_View->viewVars['access'];
}
if(!$required_level || !$user_level || $user_level != $required_level){
$accessModel = ClassRegistry::init('Access');
$access_message = $accessModel->field('access_message', array('Access.id' => $required_level));
}
return $access_message;
}
Edit 1: Ok so I did some digging to find exactly where the problem is stemming from. The USE of the component is not the problem which I thought it was before. If all I have in my component is
public function AccessMessage($required_level, $user_level) {
if(!$user_level && $this->_View->viewVars['access']){
$user_level = $this->_View->viewVars['access'];
}
if(!$required_level || !$user_level || $user_level != $required_level){
$access_message = 1;
}
return $access_message;
}
Then it works. The issue is with these two lines which are correctly implemented because they return the value for $access_message I am expecting, but they are interfering with the ability to redirect. Perhaps headers are already sent out?
$accessModel = ClassRegistry::init('Access');
$access_message = $accessModel->field('access_message', array('Access.id' => $required_level));
Please note I have also tried:
$access_message = ClassRegistry::init('Access')->field('access_message', array('Access.id' => $required_level));
And
$this->loadModel('Access');
$access_message = $this->Access->field('access_message', array('Access.id' => $required_level));
Gists:
component gist: https://gist.github.com/970a951715205c222348
controller gist: https://gist.github.com/2b90e5af2518a81672fb
access model gist: https://gist.github.com/bhndbrwneyes/f333a93f0a21302d832f
You may have space before/after php Opening/Closing tags in controller and models. Remove all the closing tags from all controllers and models and any whitespace before opening tags. Then check the result.
Not an answer yet, but at least there are some variables in your code that may not be defined, or errors that can occur:
public function AccessMessage($required_level, $user_level) {
if(!$user_level && $this->_View->viewVars['access']){
$user_level = $this->_View->viewVars['access'];
}
if(!$required_level || !$user_level || $user_level != $required_level){
$access_message = 1;
}
return $access_message;
}
Variable $access_message will only be defined if a user is not allowed to access the page
An error may occur if the 'access' viewVar is not set at all
Change it to this:
public function AccessMessage($required_level, $user_level) {
$access_message = 0;
if(!$user_level && $this->_View->get('access')){
$user_level = $this->_View->get('access');
}
if(!$required_level || !$user_level || $user_level != $required_level){
$access_message = 1;
}
return $access_message;
}
[updated] saw you did have the $access_message defined on your gist (https://gist.github.com/970a951715205c222348)
However:
This will not work
App::uses('Component', 'Controller', 'ClassRegistry', 'Utility');
App::uses() takes two arguments; the 'class' you would like to use and the location it can be found. The line above should be written as:
App::uses('Component', 'Controller/Component');
App::uses('Controller', 'Controller');
App::uses('ClassRegistry', 'Utility');
But I wonder if ClassRegistry needs to be loaded manually
[update 2] You really have a lot 'weird' things going on in your application, so I wonder if we'll be able to sort that out:
public function add($page = null) {
$access = $this->viewVars['access'];
if($this->CustomPage->AccessMessage(4, $access)){
$this->Session->setFlash(__($this->CustomPage->AccessMessage(4, $access)));
$this->redirect(array('action' => 'index', 'page' => $page));
}
// ......
}
Where is 'viewVars['access']' set?
You're passing 'viewVars['access']' as the second parameter ($user_level) to AccessMessage(), but inside AccessMessage() you're trying to use the same viewVar again if the parameter '$user_level' was not set?
$this->CustomPage->AccessMessage() is called twice once to check if it returned anything, then to use it. Not very efficient
.
public function add($page = null) {
// Where does is $this->viewVars['access'] come from? Where is it set?
$access = empty($this->viewVars['access'])? null : $this->viewVars['access'];
$message = $this->CustomPage->AccessMessage(4, $access);
if ($message) {
$this->Session->setFlash(__($message));
$this->redirect(array('action' => 'index', 'page' => $page));
}
// ......
}
On a further note. you're redirecting the user only if a 'message' was found and not empty, NOT based on the current users permissions, you might consider splitting the two;
In your component:
public function HasAccessLevel($required_level, $user_level) {
if(!$user_level || $user_level != $required_level){
return false;
}
return true;
}
public function AccessMessage($required_level) {
return ClassRegistry::init('Access')->field('access_message', array('Access.id' => $required_level));
}
In your controller:
public function add($page = null) {
// Where does is $this->viewVars['access'] come from? Where is it set?
$access = empty($this->viewVars['access'])? null : $this->viewVars['access'];
if($this->CustomPage->HasAccessLevel(4, $access)){
$this->Session->setFlash(__($this->CustomPage->AccessMessage(4)));
$this->redirect(array('action' => 'index', 'page' => $page));
}
// ......
}
Cake 2: At the top of the component: add
public function initialize(Controller $controller) {
$this->Controller = $controller;
}
inside the function you can redirect like so:
$this->Controller->redirect(array('plugin' => false, 'controller' => 'users', 'action' => 'index'));
If the redirect is called, but you are not redirected I guess you have some permission check in your index() action that prevents the access. Can you confirm or post the whole controller code?
I am trying to use render for specific action names in my app.
Actually, here are my condition set in my AppController::afterFilter()
if($this->action == 'parameter') {
$this->render('/Elements/parameter');
}
else if($this->action == 'datagrid') {
$this->render('/Elements/datagrid');
}
And in my controller /samples/parameter :
$this->set('model', Inflector::singularize(Inflector::camelize($this->name)));
$this->set('controller', $this->name);
if($parameter_id) {
$this->set('mode', $mode);
$this->set('parameter', $this->Sample->find('first', array('conditions' => array('Sample.id' => $parameter_id))));
} else {
$this->set('mode', 'add');
$this->set('parameter', array());
}
I know that I have to render AFTER the definition of variables, so I use afterFilter Something I don't understand or missed ?
Infos:
I have set in Samples Controller the function
public function afterFilter(){
parent::afterFilter();
}
Thank you all!
The afterFilter() callback is called after rendering process is done, so calling render() inside it is doing it wrong.
If you want to change the view to be rendered do so in beforeRender(). So do something like
if ($this->action == 'parameter') {
$this->view = '/Elements/parameter';
} elseif ($this->action == 'datagrid') {
$this->view = '/Elements/datagrid';
}
In my controller i have 2 actions e.g
action1() {
//code
SomeArray=();
//code
}
How can i pass all the SomeArray data to action2?
I have tried to create a public array variable in my class and pass it but with no luck.
i have tried to pass as an argument to the action2...
e.g in action1, $this->action2(SomeArray) and then action2($param) with no luck again.
function doExam($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid exam', true));
$this->redirect(array('action' => 'index'));
}
$this->Exam->recursive=1;
$conditions_question = array('Question.exam_id' => $id);
$questions = $this->Exam->Question->find('all',array('conditions' => $conditions_question));
foreach ($questions as $question) {
**$this->questionsByExam[]** = $question['Question']['qst'];
}
//OK PASSED
echo debug($this->questionsByExam);
//OK $exam_id
$this->exam_id = $id;
}
i have another action validate_answer, and i want to pass the questionsByExam in here
any help?
Thanks in advance
I have tried to create a public array variable in my class and pass it but with no luck.
Can you show the code for this? It should work fine as class variable...
E.g:
class FooController extends AppController {
var $someArray = array();
function doExam() {
// Populate the array here
$this->someArray = array(1,2,3);
}
function bar() {
// Use it here, no need to pass it as an argument
print_r($this->someArray);
}
}