How can I reset associations? - cakephp

For CakePHP2, I used following function for resetting associations.
public function unbindModelAll($reset = true) {
foreach(array('hasOne','hasMany','belongsTo','hasAndBelongsToMany') as $relation){
$this->unbindModel(array($relation => array_keys($this->$relation)), $reset);
}
}
How can I reset them for CakePHP3?

For CakePHP 2.x you can easily clear bindings using empty contain on the model
$this->Model->contain();
For CakePHP 3.x you can try, I didn't test it:
$this->Model->find()->contain();

Related

How to solve pagination-Error in cakePHP with cakeDC searchplugin

i'm using the searchplugin from cakeDC (https://github.com/CakeDC/search) with cakePHP 2.3.0. That Plugin works fine. I had a little error in the index-action like this. Thanks for that.
Indirect modification of overloaded property AtlasController::$paginate has no effect [APP\Controller\AtlasController.php, line 47]
My Index-action
public function index() {
$this->Prg->commonProcess();
$this->paginate['conditions'] = $this->Atla->parseCriteria($this->passedArgs);
$this->Atla->recursive = 0;
$this->set('atlas', $this->paginate());
$this->set('_serialize',array('atlas'));
}
The question is, how can i solve it? So i found out a way thats so simple and easy.
So this is the solution, that runs on my implementation.
I change the paginate()-call from.
$this->set('atlas', $this->paginate());
to the new paginate()-call.
this->set('atlas', $this->paginate($this->Atla->parseCriteria($this->passedArgs)));
Here the new index-action.
public function index() {
$this->Prg->commonProcess();
$this->Atla->recursive = 0;
$this->set('atlas', $this->paginate($this->Atla->parseCriteria($this->passedArgs)));
$this->set('_serialize',array('atlas'));
}
I believe the reason why the code did not work out of the box is the ['options'] key. Remove the key from $this->paginate['options'] and add the model as an argument for paginate in $this->set() and the pagination should work as expected. See the modified code example below.
public function index() {
$this->Prg->commonProcess();
$this->paginate = $this->Atla->parseCriteria($this->passedArgs);
$this->Atla->recursive = 0;
$this->set('atlas', $this->paginate('Atla'));
$this->set('_serialize',array('atlas'));
}

Detect if admin prefix is true from Model

I have made a custom afterFind function in a model, but I just want it to execute it if NOT in admin mode.
public function afterFind($results) {
if(Configure::read('Routing.admin')){
return $results;
}else{
return $this->locale(&$results);
}
}
But it doesn't seems to work. I'm thinking this might not be possible. Any idea?
checking on the core Configure settings doesnt make sense to me.
besides the fact that that 'Routing.admin' is deprecated - its Prefix.admin.
it only stores the prefixes that cake uses.
If you really want to you can store the information in configure::read() in beforeFilter() of your AppController and read it from your model again.
But it would need to something that does not conflict with your settings.
So if you use Prefix you probably could use Routing again:
//beforeFilter - prior to any model find calls!
$isAdmin = !empty($this->params['admin']);
Configure::write('Routing.admin', $isAdmin);
the other option you always have is to pass the information on to the model.
Router::getParam('prefix', true) gives you current request prefix value.
public function afterFind($results, $primary = false) {
return Router::getParam('prefix', true) == 'admin' ? $results : $this->locale(&$results);
}
Tested with Cake 2.4.

Passing data from CakePHP component to a helper

I need to share data between a component and helper. I'm converting my self-made payment service formdata generator to a CakePHP plugin and I'd like to be able to fill in the payment data from the controller(using a component) and use a helper to print out the data.
Everything I've tried so far have felt a little too hacky, so let me ask you: Is there any elegant way to pass data from a component to a helper?
edit:
I solved this particular situation by adding the original formadata class instance to ClassRegistry during the component initialization. This way the helper too can access the instance using ClassRegistry.
However, this only works for objects, so the question remains open.
Having a similar problem, I found this solution to work best for me.
You could use the helper's __construct method in pair with $controller->helpers array.
Since the Helper::_construct() is called after the Component::beforeRender, you can modify the $controller->helpers['YourHelperName'] array to pass the data to your helper.
Component code:
<?php
public function beforeRender($controller){
$controller->helpers['YourHelperName']['data'] = array('A'=>1, 'B'=>2);
}
?>
Helper code:
<?php
function __construct($View, $settings){
debug($settings);
/* outputs:
array(
'data' => array(
'A' => (int) 1,
'B' => (int) 2
)
)
*/
}
?>
I am using CakePHP 2.0, so this solution should be tested for earlier versions.
Is there any elegant way to pass data from a component to a helper?
Yes, the same way you pass any data to the helper. In your view.
Inside your component I would do something like the following. The beforeRender() action is a CakePHP component callback.
public function beforeRender(Controller $controller) {
$yourVars = 'some data';
$goHere = 'other stuff';
$controller->set(compact('yourVars', 'goHere'));
}
Then in your view you can pass the data off to your helpers just like normal.
// view or layout *.ctp file
$this->YourHelper->yourMethod($yourVars);
$this->YourHelper->otherMethod($goHere);
In addition to what #Vanja, you can also do this just prior to instantiating a new view in your controller:
// In your controller method
// must be set prior to instantiating view
$this->helpers['YourHelperName']['paramsOrAnyName'] = ['var' => $passed_var];
$_newView = new View($this);
$return_result = $_newView->render($element_to_view, $layout);

Sanitise data in cakephp

I want to sanitize data in cakephp but i am facing a problem. i have a form with a date field . When i tried to sanities all the data the date looses it's mysql format and is stored in the db as a rubbish data(1970-01-01) but if i remove the sanitize it works fine
i tried the following
function beforeSave()
{
$this->data = Sanitize::clean($this->data);
return true;
}
i also tried this and this works but it defeats the purpose
function beforeSave()
{
$date = $this->data['Cabinet']['date_of_inspection'];
$this->data = Sanitize::clean($this->data);
$this->data['Cabinet']['date_of_inspection'] = $date;
return true;
}
what is the way out
From CakePHP Manual :
CakePHP already protects you against
SQL Injection if you use CakePHP's ORM
methods (such as find() and save())
and proper array notation (ie.
array('field' => $value)) instead of
raw SQL. For sanitization against XSS
its generally better to save raw HTML
in database without modification and
sanitize at the time of
output/display.output/display.
$this->data = Sanitize::clean($this->data, array('encode' => false) solved the problem. i agree with what Jamal Aziz/Cakephp says

how to prevent an element to validate

hi to all i am using cakephp framework for my project. in on of my form i take a checkbox on click on this two other text box are shown.
by using cakephp validates method i validate the form data but i want that when the checkbox is not checked then it avoid the validation for that text box. it check only when the checkbox is checked.
so plz help me.
thanks in advance
You can use your models beforeValidate servicecall for that and add extra validation criteria for this model.
For example:
function beforeValidate($options = array())
{
if(!empty($this->data['Model']['fieldOne']))
$this->validate['fieldTwo'] = array(/*normal validation rules*/);
return true; // Needed or validation fails
}
You can use custom validation methods:
var $validate = array(
'checkbox1' => 'checkboxRule'
);
// If checkbox1 is checked, requires checkbox2 to be checked as well
function checkboxRule() {
if (!empty($this->data[$this->alias]['checkbox1'])) {
return !empty($this->data[$this->alias]['checkbox2']);
}
return true;
}
You can also invalidate other fields, like checkbox2, at the same time by calling $this->invalidate('checkbox2') in your custom method.
Also, you can unset the validation in your controller like this:
unset($this->Model->validate);

Resources