I apologize if this ends up being a newbish PHP misunderstanding, but anyway, I have the following Vip.php file:
<?php
class Vip extends AppModel {
public $useTable = 'vips';
public $hasOne = 'VipCredential';
public $belongsTo = array('User', 'MasterExhibitor');
public $validate = array();
}
class InviteVipForm extends Vip {
}
class AccreditVipForm extends Vip {
}
So, both InviteVipForm and AccreditVipForm classes should inherit every model attributes from their parent, right? This doesn't happen. I loaded InviteVipForm in the controller and printed. Everything is empty or set to default (useTable, for example, is set to invite_vip_forms, which is of course a table which doesn't exist).
AppModel Object ( [useDbConfig] => default [useTable] => invite_vip_forms [id] => [data] => Array ( ) [schemaName] => [table] => invite_vip_forms [primaryKey] => id [_schema:protected] => [validate] => Array ( ) [validationErrors] => Array ( ) [validationDomain] => [plugin] => [name] => InviteVipForm [alias] => InviteVipForm [tableToModel] => Array ( [invite_vip_forms] => InviteVipForm ) [cacheQueries] => [belongsTo] => Array ( ) [hasOne] => Array ( ) [hasMany] => Array ( ) [hasAndBelongsToMany] => Array ( ) [actsAs] => [Behaviors] => BehaviorCollection Object ( [modelName] => InviteVipForm [_methods:protected] => Array ( ) [_mappedMethods:protected] => Array ( ) [_enabled:protected] => Array ( ) [_loaded:protected] => Array ( ) [defaultPriority] => 10 ) [whitelist] => Array ( ) [cacheSources] => 1 [findQueryType] => [recursive] => 1 [order] => [virtualFields] => Array ( ) [_associationKeys:protected] => Array ( [belongsTo] => Array ( [0] => className [1] => foreignKey [2] => conditions [3] => fields [4] => order [5] => counterCache ) [hasOne] => Array ( [0] => className [1] => foreignKey [2] => conditions [3] => fields [4] => order [5] => dependent ) [hasMany] => Array ( [0] => className [1] => foreignKey [2] => conditions [3] => fields [4] => order [5] => limit [6] => offset [7] => dependent [8] => exclusive [9] => finderQuery [10] => counterQuery ) [hasAndBelongsToMany] => Array ( [0] => className [1] => joinTable [2] => with [3] => foreignKey [4] => associationForeignKey [5] => conditions [6] => fields [7] => order [8] => limit [9] => offset [10] => unique [11] => finderQuery ) ) [_associations:protected] => Array ( [0] => belongsTo [1] => hasOne [2] => hasMany [3] => hasAndBelongsToMany ) [__backAssociation] => Array ( ) [__backInnerAssociation] => Array ( ) [__backOriginalAssociation] => Array ( ) [__backContainableAssociation] => Array ( ) [__safeUpdateMode] => [_insertID:protected] => [_sourceConfigured:protected] => [findMethods] => Array ( [all] => 1 [first] => 1 [count] => 1 [neighbors] => 1 [list] => 1 [threaded] => 1 ) [_eventManager:protected] => [_validator:protected] => )
Could anybody tell me why this is happening? The classes don't need to be in separate files, do they?
That's not how things work, each model has to be placed in a separate file, otherwise CakePHP might not be able to find/load them, and then you'll end up with an instance of the AppModel class being used, which is what you are experincing.
The AppModel instance of course won't have any of the properties or methods that you've defined on your extending class.
This behavior is also mentioned in the Cookbook, see http://book.cakephp.org/2.0/en/models.html
CakePHP will dynamically create a model object for you if it cannot find a corresponding file in /app/Model. This also means that if your model file isn’t named correctly (for instance, if it is named ingredient.php or Ingredients.php rather than Ingredient.php), CakePHP will use an instance of AppModel rather than your model file (which CakePHP assumes is missing). If you’re trying to use a method you’ve defined in your model, or a behavior attached to your model, and you’re getting SQL errors that are the name of the method you’re calling, it’s a sure sign that CakePHP can’t find your model and you need to check the file names, your application cache, or both.
Related
I am using php with codeigniter. When I did the print_r, I got the following:
Array
(
[0] => stdClass Object
(
[UserName] => fun
[UserCode] => 6
[GroupCode] => 1
[GroupName] => Master
[MenuCode] => 0
[MenuName] =>
[Admin] => 0
)
[1] => stdClass Object
(
[UserName] => fun
[UserCode] => 6
[GroupCode] => 1
[GroupName] => Master
[MenuCode] => 1
[MenuName] => Item Master
[Admin] => 0
)
)
In another hands I have another set of array,
Array
(
[0] => Billing Report
[1] => Waiterwise Report
[2] => Admin
[3] => User Master
[4] => User Rights
[5] => Close Session
[6] => Close Day
)
Now i want to compare Group name in the above two array and want the key as result.
Try this
$result_array = array();
foreach($codeigniter_array as $k=>$r)
{
foreach($r as $k1=>$r1)
{
if(in_array($r1, $group_array))
{
$result_array[$k1] =$r1;
}
}
}
print_r($result_array);die;
I have a HABTM relationship in both my models.
Person.php
public $hasAndBelongsToMany = array(
'Tag' =>
array(
'className' => 'Api.Tag'
));
Tag.php
public $hasAndBelongsToMany = array(
'Person' =>
array(
'className' => 'Api.Person',
));
PeopleController.php
public function edit(){
$results = $this->Person->saveAll($this->request->data);
}
_
(
[id] => 554d92e1-7920-409a-b348-080e2773a233
[firstname] => George
[lastname] => Jones
[Company] => Array
(
[id] => 554995a3-f880-4a02-b971-9ac82773a233
[title] => xxxx
)
[Tag] => Array
(
[0] => Array //this is an existing tag
(
[id] => 530e487c-44bc-4ffe-ae2b-152f4056922c
[title] => monkey
[PeopleTag] => Array
(
[id] => 554e741d-a98c-48d0-8a52-080c2773a233
[tag_id] => 530e487c-44bc-4ffe-ae2b-152f4056922c
[person_id] => 554d92e1-7920-409a-b348-080e2773a233
[created] => -62169987600
[modified] => 1431207117
)
)
[1] => Array //this is a new tag that's not being added
(
[title] => rocketship
)
[2] => Array //this is a new tag that's not being added
(
[title] => houses
)
)
)
When I manually set tags in the database I'm able to read them back out into my app correctly and when I delete existing tags, they get removed from the database. The problem is though that nothing gets added when I try to use cakephp to add them.
My data array looks a little funky because I'm actually using this plugin to transform things.
http://friendsofcake.com/crud/docs/listeners/api-transformation.html
my CakePHP app is getting this data below, but it's not adding my new tags nor is it adding my associations in the people_tags join table. Any idea on what I'm doing wrong?
[0] => Array
(
[Host] => Array
(
[id] => 2821
[user_id] => 7090
)
[Review] => Array
(
[0] => Array
(
[id] => 852
[host_id] => 2821
[user_id] => 6592
)
[1] => Array
(
[id] => 853
[host_id] => 2821
[user_id] => 6532
)
)
[1] => Array
(
[Host] => Array
(
[id] => 2221
[user_id] => 7390
)
[Review] => Array
(
)
)
I want to show order of pagination result on basis of count review of host.I am trying to use concept of virtual fields to sort.
Please help me to suggest this ..
Refer to Cakephp websie
The implementation of virtualFields has a few limitations. First you
cannot use virtualFields on associated models for conditions, order,
or fields arrays.
However workaround is something along the lines with:
Review Model:
public $virtualFields = array('rw_count' => COUNT(Review.host_id));
Host Model:
class Host extends Model{
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$this->virtualFields['rw_count'] = $this->Review->virtualFields['rw_count'];
}
}
Hosts Controller
public $paginate = array(
'limit' => 25,
'order' => array(
'rw_count' => 'desc'
)
);
Given that I don't have full details of your schema, this is what I presume what you could use but the concepts remain the same
I am a Yii beginner and am running into a bit of a wall and hope someone will be able to help me get back onto track. I think this might be a fairly straight forward question to the seasoned Yii user. So here goes...
In the controller, let's say I run the following call to the model-
$variable = Post::model()->findAll();
All works fine and I pass the variable into the view. Here's where I get pretty stuck. The array that is returned in the above query is far more complex than I anticipated and I'm struggling to make sense of it. Here's a sample-
print_r($variable);
gives-
Array ( [0] => Post Object ( [_md:CActiveRecord:private] => CActiveRecordMetaData Object ( [tableSchema] => CMysqlTableSchema Object ( [schemaName] => [name] => tbl_post [rawName] => `tbl_post` [primaryKey] => id [sequenceName] => [foreignKeys] => Array ( ) [columns] => Array ( [id] => CMysqlColumnSchema Object ( [name] => id [rawName] => `id` [allowNull] => [dbType] => int(11) [type] => integer [defaultValue] => [size] => 11 [precision] => 11 [scale] => [isPrimaryKey] => 1 [isForeignKey] => [autoIncrement] => 1 [_e:CComponent:private] => [_m:CComponent:private] => ) [post] => CMysqlColumnSchema Object ( [name] => post [rawName] => `post` [allowNull] => [dbType] => text [type] => string [defaultValue] => [size] => [precision] => [scale] => [isPrimaryKey] => [isForeignKey] => [autoIncrement] => [_e:CComponent:private] => [_m:CComponent:private] => ) ) [_e:CComponent:private] => [_m:CComponent:private] => ) [columns] => Array ( [id] => CMysqlColumnSchema Object ( [name] => id [rawName] => `id` [allowNull] => [dbType] => int(11) [type] => integer [defaultValue] => [size] => 11 [precision] => 11 [scale] => [isPrimaryKey] => 1 [isForeignKey] => [autoIncrement] => 1 [_e:CComponent:private] => [_m:CComponent:private] => ) [post] => CMysqlColumnSchema Object ( [name] => post [rawName] => `post` [allowNull] => [dbType] => text [type] => string [defaultValue] => [size] => [precision] => [scale] => [isPrimaryKey] => [isForeignKey] => [autoIncrement] => [_e:CComponent:private] => [_m:CComponent:private] => ) ) [relations] => Array ( [responses] => CHasManyRelation Object ( [limit] => -1 [offset] => -1 [index] => [through] => [joinType] => LEFT OUTER JOIN [on] => [alias] => [with] => Array ( ) [together] => [scopes] => [name] => responses [className] => Response [foreignKey] => post_id [select] => * [condition] => [params] => Array ( ) [group] => [join] => [having] => [order] => [_e:CComponent:private] => [_m:CComponent:private] => ) ) [attributeDefaults] => Array ( ) [_model:CActiveRecordMetaData:private] => Post Object ( [_md:CActiveRecord:private] => CActiveRecordMetaData Object *RECURSION* [_new:CActiveRecord:private] => [_attributes:CActiveRecord:private] => Array ( ) [_related:CActiveRecord:private] => Array ( ) [_c:CActiveRecord:private] => [_pk:CActiveRecord:private] => [_alias:CActiveRecord:private] => t [_errors:CModel:private] => Array ( ) [_validators:CModel:private] => [_scenario:CModel:private] => [_e:CComponent:private] => [_m:CComponent:private] => ) ) [_new:CActiveRecord:private] => [_attributes:CActiveRecord:private] => Array ( [id] => 1 [post] => User Post ) [_related:CActiveRecord:private] => Array ( ) [_c:CActiveRecord:private] => [_pk:CActiveRecord:private] => 1 [_alias:CActiveRecord:private] => t [_errors:CModel:private] => Array ( ) [_validators:CModel:private] => [_scenario:CModel:private] => update [_e:CComponent:private] => [_m:CComponent:private] => ) )
[sorry if there's an easier way to show this array, I'm not aware of it]
Can anyone explain to me why the model returns such a complex array? It doesn't seem to matter what tables or columns or relations are used in your application, they all seem to me to return this format.
Also, can someone explain the structure to me so that I can isolate the variables that I want to recover?
Many thanks in advance,
Nick
Better print_r
To get a better print_r output in yii, you can use the CVarDumper class' dump() or dumpAsString() methods. They also provide a parameter $highlight which will help you make sense of the output, by properly formatting the output, and adding indentation to it. Example:
CVarDumper::dump($variables,10,true);
// 10 is the default depth, and passing true will enable highlighting
Why and what structure?
As already mentioned in the other answers findAll() returns an array of CActiveRecord objects, so $variables is an array of objects, and $variables[0] is the first Post object. Yii's CActiveRecord has a host of properties which are objects, for instance a CActiveRecordMetaData object, which in turn has a CDbTableSchema object (and you have it's subclass the CMysqlTableSchema, which means you are using mysql). The print_r is simply printing out these objects, which are nothing but properties of the main CActiveRecord object. In addition to these objects the attributes property(which is an array) of a CActiveRecord holds your actual attribute values, so somewhere in the output you'll also see an array like this:
[CActiveRecord:_attributes] => array
(
'attributeName' => 'attributeValue'
'anotherAttributeName' => 'anotherAttributeValue'
'someAttributeName' => 'someAttributeValue'
...
)
Those are your attribute values.
How to access?
To access a model's properties we can use both object property access, and associative array access(Probably because CActiveRecord's parent class CModel implements php's ArrayAccess interface). Example:
$variables[0]->attributeName;
$variables[0]['attributeName'];
And since yii uses and overrides the __get php magic method we can do:
$variables[0]->attributeName;
// instead of
$variables[0]->attributes['attributeName'];
And of course you can iterate over the array of Post objects using foreach() as already shown in another answer here:
foreach($variables as $aPost){
echo $aPost->attributeName;
echo $aPost['attributeName'];
echo $aPost->attributes['attributeName'];
}
To access relations, just use the relation name:
$variables[0]->relationName->attributeOfRelatedTable;
$variables[0]['relationName']->attributeOfRelatedTable;
$variables[0]['relationName']['attributeOfRelatedTable'];
If your relation is HAS_MANY, then of course the related models will also be returned as an array:
$variables[0]->relationName[0]->attributeOfRelatedTable;
$variables[0]['relationName'][0]->attributeOfRelatedTable;
$variables[0]['relationName'][0]['attributeOfRelatedTable'];
$variables[0]->relationName[0]['attributeOfRelatedTable'];
And again you can iterate over the relations array incase of HAS_MANY relations.
Edit: example for has_many iteration:
foreach($variables as $aPost) { // get each post one by one
echo $aPost->someAttribute; // or $aPost['someAttribute']
foreach($aPost->relationName as $aComment) { // say we get each comment of each post
// or could have done $aPost['relationName'] as $aComment
echo $aComment->commentAttribute; // or $aComment['commentAttribute']
}
}
findall returns an array of active records for your model see here
Once you have that you can access all the columns in each record returned like so
$results = Post::model()->findAll();
foreach($results AS $model)
{
echo $model->somecolumnname;
echo $model->someothercolumnname;
}
So you don't have to concern yourself too much with all that detail under the hood as you can just use the abstraction directly.
A simple answer to this is to use,
print_r($variable->attributes);
where $variable is an object of Model Class.
I have the following model relationships defined:
class Publication extends AppModel {
var $name = 'Publication';
var $hasAndBelongsToMany = array(
'Author'=>array(
'className'=>'Author'
)
);
}
class Author extends AppModel {
var $name = 'Author';
var $hasAndBelongsToMany = array(
'Publication'=>array(
'className'=>'Publication'
)
);
var $belongsTo = array(
'College' => array (
'className' => 'College'
)
);
}
class College extends AppModel {
var $name = 'College';
var $hasMany = array(
'Department'=>array(
'className'=>'Department'
)
);
}
class Department extends AppModel {
var $name = 'Department';
var $belongsTo = array(
'College'=>array(
'className'=>'College'
)
);
}
The database tables are set up correctly (join tables for the HABTM, etc.). I am trying to find the one DB query to rule them all. I want to create a query that will find all of the publications with the associated authors, colleges, departments, etc. After getting data from a form, I have tried to run queries like this:
$conditions = array(
"Author.id" => $this->data['authors'],
"Publication.year" => $this->data['year']
);
$publications = $this->Publication->find('all', array('conditions' => $conditions));
This throws SQL errors saying that Author.id is not a valid field. Now, this is because a join with the 'authors' db table has not been completed by the time Author.id is being searched for. BUT, if I do this:
$pubs = $this->Publication->find('all', array('conditions' => $conditions));
then I get an array that has all of the Publications with all of the associated Authors (though, not the associated Colleges for some reason).
My question is this: what do I need to do to make the tables join before Author.id is searched for? I've attempted to use bindModel, containable, subqueries, but cannot get those to work for some reason (probably a ID10T error).
Thanks for any advice!
Edit:
The result of the following call:
$this->Publication->recursive = 2;
$pubs = $this->Publication->find('all');
are as follows:
Array (
[0] => Array (
[Publication] => Array ( [id] => 1 [title] => TestArticle [year] => 2011 [type_id] => 3 )
[Type] => Array ( [id] => 3 [type_name] => Journal Articles )
[Author] => Array (
[0] => Array ( [id] => 2 [firstname] => Jeremy [lastname] => Gustine [middle] => A [faculty] => 0 [college_id] => 4 [AuthorsPublication] => Array ( [id] => 3 [author_id] => 2 [publication_id] => 1 )
[College] => Array ( [id] => 4 [college_name] => Letters, Arts, and Sciences ) )
[1] => Array ( [id] => 3 [firstname] => George [lastname] => Obama [middle] => A [faculty] => 0 [college_id] => 6 [AuthorsPublication] => Array ( [id] => 2 [author_id] => 3 [publication_id] => 1 )
[College] => Array ( [id] => 6 [college_name] => School of Public Affairs ) )
[2] => Array ( [id] => 2 [firstname] => Jeremy [lastname] => Gustine [middle] => A [faculty] => 0 [college_id] => 4 [AuthorsPublication] => Array ( [id] => 1 [author_id] => 2 [publication_id] => 1 )
[College] => Array ( [id] => 4 [college_name] => Letters, Arts, and Sciences ) ) ) )
[1] => Array (
[Publication] => Array ( [id] => 2 [title] => TestBook [year] => 2010 [type_id] => 1 )
[Type] => Array ( [id] => 1 [type_name] => Books )
[Author] => Array (
[0] => Array ( [id] => 7 [firstname] => Sony [lastname] => Stuff [middle] => L [faculty] => 0 [college_id] => 5 [AuthorsPublication] => Array ( [id] => 4 [author_id] => 7 [publication_id] => 2 )
[College] => Array ( [id] => 5 [college_name] => Nursing and Health Science ) ) ) ) )
Hopefully that is somewhat readable...
Your second find is correct
i.e. $pubs = $this->Publication->find('all', array('conditions' => $conditions));
just above that try using recursive 2 (below code) to get related College too.
$this->Publication->recursive = 2;