is there a way of automatic converting from array to Zend_Db_Table_Row or Zend_Db_Table_Rowset?
Form Zend_Db_Table_Row you can get the array with toArray(), but I was wondering if there exits anything like opposite of that?
Till now I have been implementing a function fill($data) which took the array and than set the atributes of Zend_Db_Table_Row.
Of course array keys are the same as Zend_Db_Table_Row attributes.
Thanx!
Check the Zend_Db_Table's fetchRow() method. There you can find it. I guess you can feed the array to the constructor like this:
$data = array(
'table' => $yourDbTableModel,
'data' => $yourArray,
'readOnly' => $iGuessShouldBeZero,
'stored' => true
);
$row = new Zend_Db_Table_Row($data);
I think this should do the trick:
$myRow = new Zend_Db_Table_Row(
array(
'data' => array( /* your array with data */ )
)
);
So, if you provide the constructor with a config array that holds a key 'data' that in it's turn holds an array with the data, you should be good.
For more info look into Zend_Db_Table_Row_Abstract in your Zend library.
Related
My CakePHP Cart model/table has only one field: id.
It hasMany LineItems.
I am not having success saving the Cart model alone:
$this->Cart->create();
$this->Cart->save();
Or, by passing it a $data array structured as follows and using saveAssociated():
$data = array(
'Cart' => array(),
'LineItem' => array(
array(
'item_id' => $item_id,
'qty' => $qty,
'price_option_id' => $price_option_id
)
)
);
If I add a useless_field to the Cart table/model, and pass some data in it saves. So obviously the problem lies in my having a model with a table with just a single id field and not passing in any other data to save. It won't create what it must be assuming is an 'empty' record.
I have passed 'validate' => false into the saveAssociated call but it doesn't make a difference (and there are no validations for this model to ignore).
Is there a way to do this? Am I missing something? Please enlighten me!
CakePHP tables require created and modified fields, or for you to define your own fields (ie you can call them whatever you want but they do the same thing).
In this instance you would use
$this->Cart->set($data);
$this->Cart->saveAll();
I am using CakePHP 2.1.3; I want to create a virtual field dynamically in a controller. Is it possible?
The problem is when I am trying to find max value in a table it gives me another array from the model array. Please ask if you need more information.
When I am trying to execute the following query,
$find_max_case_count = $this->CaseMaster->find('first', array(
'conditions' => array(
'CaseMaster.CLIENT_ID' => $client_id,
'CaseMaster.CASE_NO LIKE' => '%-%'
),
'fields' => array('max(CaseMaster.CASE_NO) AS MAX_NO')
));
It is giving me an array like:
[0]=> array([MAX_NO]=> 52)
However I want it to be like as:
[CaseMaster] => array([MAX_NO] => 52)
I found a solution. I can make the virtual field at runtime. The code should looks like:
$this->CaseMaster->virtualFields['MAX_NO'] = 0;
Write it just above the find query and the query will remain same as it was written.
This link was helpful to find out the solution.
There is no way (as far as I am knowledgeable) to create virtual fields "on the fly". What virtual fields are is "arbitrary SQL expressions" that will be executed when a find runs through the Model and "will be indexed under the Model's key alongside other Model fields".
What do you need to do with "dynamically created virtual fields"? If you explain what exactly you need to accomplish maybe we can provide a different (even more suitable? :) ) solution? I'd personally be happy to help you.
After you editing your question I can say that what you're getting is the way the array should be returned, this is because of the fields parameter. If you want to get a different structure out of it I suggest applying a callback to format it.
Firstly move the method inside the CaseMaster Model:
public function getMaxCaseCount($client_id){
$data = $this->find('first', array(
'conditions' => array(
'CaseMaster.CLIENT_ID' => $client_id,
'CaseMaster.CASE_NO LIKE' => '%-%'),
'fields' => array('max(CaseMaster.CASE_NO) AS MAX_NO')));
return array_map(array('CaseMaster', '__filterMaxCaseCount'), $data);
}
private function __filterMaxCaseCount($input){
//This is just an example formatting
//You can do whatever you would like here.
$output['CaseMaster'] = $input[0];
return $output;
}
The array_map function will apply the __filterMaxCaseCount callback method so that when you call:
$this->CaseMaster->getMaxCaseCount($client_id);
from your controller you will get the data in the way you need it. The array_map function could also look like this:
return array_map(array($this, '__filterMaxCaseCount'), $data);
because you're in the same Class.
Just adding your model alias to field definition also works for this purpose
'fields' => array('max(CaseMaster.CASE_NO) AS CaseMaster__MAX_NO')
How to append to contain when it's already declared?
I call a regular contain/find:
// A controller
$this->Site->contain(array('User'));
$site = $this->Site->find();
I want to automatically add something to contain. I was thinking of doing this in the Model by adding to the find function... something like this:
// Site.php Model
function find($conditions = null, $fields = array(), $order = null, $recursive = null) {
if(!isset($this->containVariable) || !in_array('Box', $this->containVariable)) {
$this->containVariable[] = 'Box';
}
parent::find($conditions, $fields, $order, $recursive);
}
To make this work (automatically adding model Box to contain) I only need to change $this->containVariable by a function or variable that has an array of what's already in contain. In this case this would return array('User'). How to append to contain when it's already declared? Is there a variable that contains contain?
Unless someone can find another solution I've came to the conclusion that:
Unfortunately what I was trying to do seems impossible how containable is designed. I had to manually add my model to every ->contain() calls.
I fixed perhaps a similar issue with persisting contain for multiple find calls (using cakephp 1.3). After declaring contain for a certain model, this will be set for that model:
$this->Behaviors->Containable->runtime
-where $this is some model object. 'runtime' is an array that essentially holds the contain information. So you are close I believe, but instead of:
$this->containVariable[] = 'Box'
You would have:
$this->Behaviors->Containable->runtime['someModel']['contain'][] = 'Box'
To be able to specify more than just the model though, you would have to set up to handle like the following (perhaps build a method accordingly):
$this->Behaviors->Containable->runtime['someModel']['contain'][] = $model_contain_array
$model_contain_array is just an arbitrary name I just chose for an array which holds the contain information you would like to add for a particular model. An example of $model_contain_array might be:
array('modelName' => array(
'fields' => array('id', 'other'),
'otherModelName' => array(
'fields' => array('id', 'otherfield', 'etc')
)
)
Cake Php Read function to retrieve result as simple array
$result = $this->Model->read('id, name, title', $id);
It will result as
Array
(
[Model] => Array
(
[id] => 1
[name] => test
[title] => New Head title
)
)
It there any way to retrieve result array directly from query as below
Array
(
[id] => 1
[name] => test
[title] => New Head title
)
Without using any temp storage of a variable.
Just run the result through a Set::extract call, like this:
$result = $this->Model->read('id, name, title', $id);
$result = Set::extract('/Model', $result);
Set is a very powerful class, I suggest you read on it. :)
Cheers.
CakePHP purity aside (agree with other posters though)
Is find('list') what you are looking for?
$result = $this->Model->find('list', array('fields' => array('id', 'name', 'title'), 'conditions' => array('id' => $id), 'recursive' => 0 ));
Unless you're going to hack the Cake core, Cake will always internally return the results using the extra model key. So "without using any temp storage of a variable" is pretty much impossible, if you mean this in terms of "speed optimization" (in quotes, because it hardly makes any difference).
You can make it work simply with:
$result = current($this->Model->read('id, name, title', $id));
You could override the model's read method so it always does this internally (not recommended, it'll come to bite you one day). You could do so in the AppModel to have this behavior globally.
I have a model with the name Deal class Deal extends AppModel
Now in my controller I call a method in the Deal model called getDeal()
$dealInfo = Deal::getDeal($dealID);
I want the info returned to me but the var_dump displays blank
function getDeal($dealID){
$deal = $this->Deal->find('first', array(
'conditions' =>
'Deal.id' =>$dealID
) ,
'fields' => array(
'Deal.id'
) ,
'recursive' => 1,
));
}
This is the first time I'm working in cakePHP, so this question might sound a bit dumb
When you're just using an id as your find condition you can use CakePHP's dynamic finder methods.
Dynamic finders work like this.
$this->Model->findByModelFieldName();
In your example it would be
$this->findById($dealId, array(
'fields' => array('Deal.id'),
'recursive' => 1
));
I don't know if I'm just being mental, but is this simply because you're not returning anything from getDeal()?
Try adding return $deal; and see if that helps. Your question doesn't state exactly where you're doing the var_dump so I might be well off.
Edit:
As per the discussion with you and 8vius, we've established that this isn't right, and you simply need to change $this->Deal->find() to $this->find() because its being run from the model.
Check your function declaration, $deal_id does not exist and as you can see from the parameter you pass to the function which should me $deal_id and not dealID. So you have a misdeclared function calling find with a variable that does not exist.