Containable "contain" property not being reset - cakephp

Containable is not behaving as I expect in CakePHP 2.1.2 in the following code:
class ReportCard extends AppModel {
....
// debug shows expected results
public function test1(){
$this->Behaviors->attach('Containable');
$params = array(
'conditions' => array('ReportCard.id' => 1),
'contain' => array(
'ReportCardGradingPeriodCollection' => array(
'GradingPeriodCollection')));
debug($this->find('first', $params));
$this->Behaviors->detach('Containable');
}
// Unexpected: debug shows same array as test1
public function test2(){
$this->Behaviors->attach('Containable');
$params = array(
'conditions' => array('ReportCard.id' => 1),
'contain' => array(
'ReportCardGradingPeriodCollection' => array(
'GradingPeriodCollection' => array(
'GradingPeriodCollectionDetail' => array(
'GradingPeriod')))));
debug($this->find('first', $params));
$this->Behaviors->detach('Containable');
}
}
I get unexpected results when calling the functions from the controller. test1() shows the expected array. test2() shows the same array from test1. If I run test2() then test1() I get expected results (large array, then small array).
class ReportCardsController extends AppController {
....
public function test(){
$this->ReportCard->test1();
$this->ReportCard->test2();
}
}
I have tried using actAs in the model instead of dynamically loading the behavior in each function, but that did not help.
I apologize if I'm missing something simple. Thanks in advance!

Quoting the manual:
Containable must to be attached to all models used in containment,
From your example code it's not clear whether you are doing that.
And here's the remaining half of that note:
you may consider attaching it to your AppModel.

Related

How do I set up an adapter in zend framework 2?

this is the content of the autoload/global.php file :
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=web_builder;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
this is the content of the autoload/local.php file:
return array(
'db' => array(
'username' => 'DB_User_Name',
'password' => 'DB_Password',
,
); )
this is part of the content of module/Module.php :
namespace Application;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Zend\Db\Adapter\Adapter;
.........
public function getServiceConfig() {
return array(
'factories' => array(
'Application\Controller\UserController' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new Model\StickyNotesTable($dbAdapter);
return $table;
},
),
);
}
Here I really don't understand what this function do, I just copy pasted from an example. If you could explain me what does getServiceConfig function do, I will really appreaciate it.
Finally the controller content:
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Db\Adapter\Adapter;
use Zend\Db\TableGateway\AbstractTableGateway;
use Zend\Db\Sql\Select;
class UserController extends AbstractActionController{
public function __construct(Adapter $adapter) {
$this->adapter = $adapter;
}
public function loginAction(){
// here i just want to a simple select and yes I know queries will be executed
//in Model, but I want to here a simple query.
//For example in Codeigniter I can't do in model, controller, or view as well.
return new ViewModel();
}
The result of all this code is obviously an error:
Catchable fatal error: Argument 1 passed to Application\Controller\UserController::__construct() must be an instance of Zend\Db\Adapter\Adapter, none given, called in C:\xampp\htdocs\zf2\vendor\zendframework\zendframework\library\Zend\ServiceManager\AbstractPluginManager.php on line 170 and defined in C:\xampp\htdocs\zf2\module\Application\src\Application\Controller\UserController.php on line 21
Can someone post an answer to make this database or query stuff work ? thx

CakePHP: drop-down list with database fields

I've got this relationship between two models:
Snippet belongsTo SnippetCategory
SnippetCategory hasMany Snippet
I need a drop-down list of SnippetCategories when I add a new Snippet. For this, I've got the following code:
//Snippet.php
public $belongsTo = array(
'SnippetCategory' => array(
'className' => 'SnippetCategory',
'foreignKey' => 'snippet_category_id'));
//SnippetCategory.php
public $hasMany = array(
'Snippet' => array(
'className' => 'Snippet',
'foreignKey' => 'snippet_category_id',
'dependent' => true));
//SnippetsController.php
public function add() {
$categories = $this->Snippet->SnippetCategory->find('list');
$this->set(compact('categories'));
if ($this->request->is('post')) {
$this->request->data['Snippet']['user_id'] = $this->Auth->user('id');
if ($this->Snippet->saveAssociated($this->request->data)) {
$this->Session->setFlash('Snippet saved.');
$this->redirect(array('action' => 'index'));
}
}
}
//Snippets/add.ctp
// ...html...
echo $this->Form->input('categories', array(
'tabindex' => 2));
// ...html...
But I'm getting a "Call to a member function find() on a non-object" error. I know it has to be some stupid error, but I'm not able to find what I'm doing wrong...
Please, someone could help me with this? Thanks in advance!
First of all, you should post the whole code from the Snippet and SnippetCategory model. Maybe there's something that is causing this oddly behavior that is not shown in this snippet of code.
The error is quite straight forward, SnippetCategory is not initialized.
You can always use:
$this->loadModel('SnippetCategory');
$this->SnippetCategory->find('list');
But it's not the smarttest way because SnippetCategory model must be initialized with the Snippet model

CakePHP Pagination 'conditions' limited by $this->Session->read()

I'm trying to limit my pagination results by the $this->Session->read('Player.team_id')... so that the logged in user can only see his related team members.
PlayersController.php
public $paginate = array(
'conditions' => array(
'Player.team_id' => $this->Session->read('Player.0.Team.id')
),
'limit' => 20,
'order' => array('Player.fullname' => 'asc')
);
public function index() {
$this->Paginator->settings = $this->paginate;
$this->Player->recursive = 0;
$this->set('players', $this->Paginator->paginate());
}
This causes an error when viewing player/index
Error: syntax error, unexpected T_VARIABLE
File: /home/www/public_html/dev/app/Controller/PlayersController.php
Line: 21
If I hardcode the 'conditions' as below then it works fine and only retrieves the records I want
'conditions' => array('Player.team_id' => 1)
In the Player.php model login action it writes the Session Variable Team.id and Team.name.
I have used the $this->Session->read else where in my app (views and other models) and it works fine. It just doesn't seem to work with in the pagination component?
This is simply invalid PHP syntax, class members can only be initialized with constant values, that is values that can be evaluated at compile time (strings, numbers, booleans, arrays, etc...)
Assign the session value at runtime in the Controller::beforeFilter() callback (or even directly in the index() action in case appropriate) instead:
public $paginate = array(
'limit' => 20,
'order' => array('Player.fullname' => 'asc')
);
public function beforeFilter() {
parent::beforeFilter();
$this->paginate['conditions'] = array(
'Player.team_id' => $this->Session->read('Player.0.Team.id')
);
}
Also as pointed out in the comments, make sure that the session key you are accessing actually exists and holds the expected value!
See also http://www.php.net/manual/en/language.oop5.properties.php

Cakephp paginator array error

I'm new to CakePHP and have a question about this controller:
function showmy($userid) {
return $this->Voucher->find('all', array('conditions' => array('Voucher.user_id' => $userid)));
}
public function index() {
$this->Voucher->recursive = 0;
$userid = $this->Session->read('Auth.User.id');
$this->set('vouchers', $this->showmy($userid ));
}
I want all the Voucher with user_id by the loged in user.
It works, but i get many errors like :
Warning (2): array_filter() expects parameter 1 to be array, null given [CORE\Cake\View\Helper\PaginatorHelper.php, line 419]
Maybe someone with more experienced could give me some advice!
Thanks,
Julius
I think you need to use PaginatorComponent::paginate() to be able to use the PaginatorHelper in your view. More info in the manual.
You must declare $paginate array in you controller for the pagination
public $paginate = array(
'limit' => 25,
'order' => array(
'Post.title' => 'asc'
)
);
paginate => array
public function index() {
$this->Voucher->recursive = 0;
$userid = $this->Session->read('Auth.User.id');
$this->Paginator->settings = array(
array('conditions' => array('Voucher.user_id' => $userid))
);
$this->set('vouchers', $this->Paginator->paginate('Voucher'));
}

Cakephp testAction() is not sending a json payload to controller

I am trying to test a controller function that accepts a json payload.
As per the documentation of testAction() this can be done via setting $options['data'] to the appropriate string. Its not working for me.
See the documentation quoted here: http://api20.cakephp.org/class/controller-test-case (Please scroll down the the testAction() section).
Here is my test case.
public function testCreate(){
//Some code here
$this->testAction('/shippingbatches/create', array('data' => '[3,6]', 'method' => 'post'));
//Some more code here
}
Here is my controller function
public function create(){
debug($this->request); //This debug shows me an empty array in $this->request->data
ob_flush();
$order_ids = json_decode($this->request->data);
//Some more code here
}
The first line of the controller function is showing me an empty array in $this->request->data. If the 'data' passed from the testAction() is an actual array it comes in nice & fine. But not when it is set to a string (unlike it says in the documentation).
Here is the output of the debug.
object(Mock_CakeRequest_ef4431a5) {
params => array(
'plugin' => null,
'controller' => 'shippingbatches',
'action' => 'create',
'named' => array(),
'pass' => array(),
'return' => (int) 1,
'bare' => (int) 1,
'requested' => (int) 1
)
data => array()
query => array(
'case' => 'Controller\ShippingBatchesController'
)
url => 'shippingbatches/create'
base => ''
webroot => '/'
here => '/shippingbatches/create'
}
Please help.
Gurpreet
When passing data like that, you must receive it using CakeRequest::input().
public function create() {
$json = $this->request->input('json_decode', true);
debug($json);
}
I should note that I discovered this by reading Cake's test cases for ControllerTestCase::testAction. Reading test cases can give you insight into how Cake's internals work and give you hints on writing tests.

Resources