CakePHP - Post type without dB table - cakephp

What's the best way of doing this in cakephp:
I have a Posts model+view+controller with a "Post type" field in my database - linking to my post type id.
The post type ids are:
- Preview
- Review
- News
What I'm asking is: What's the best way (natively) of retrieving the post type name, without creating a table Post_types and linking it with a post_id.
I tried creating an array in the config lists, it worked but I think it can be better then this.

You could use the afterFind method of your Post model and add there a post_type field to your results. See also the cookbook.

From what I understand your post_type is a enum field with values preview, review, news or a varchar in which you know only add these 3 types, right?
You could try the following query
SELECT DISTINCT(post_type) FROM posts;
This will return all post_types that are being used in your posts table.
In Cake you could do this either with the find or query method.
# Using find
$this->Post->find('all', array(
'fields' => array('DISTINCT(post_type)')
);
# Or using the query directly (maybe easier in this case)
$this->Post->query("SELECT DISTINCT(post_type) FROM posts;");

associate your table posts with the table post_types with $hasOne.
With a e.g.
$this->Post->find('all');
you would get the post and the post_type in one array.

Related

Laravel get value of column from relation through pivot on load() after all()

I have a problem retrieving values of a column from relations in Laravel.
I have a User - Model. This model has relation to a table btw. a model named Userhobbies.
For now we have:
User ::: hasMany >>> Userhobbies
Now with User::all()->load('hobbies') I'm getting right results like
{"id":"1","username":"jdoe","first_name":"Joe","last_name":"Doe","birth":"
1992-04-11","picture_id":"f3dca65323e876026b409b9ba3d49c56","hobbies":
[{"hobby_id":"1","user_id":"1"},{"hobby_id":"2","user_id":"1"},
{"hobby_id":"3","user_id":"1"},{"hobby_id":"4","user_id":"1"}]}
As you can see Userhobbies contains only primary-key relations between hobby - table (Hobby Model) and user - table (User Model).
(Hobby model also has hasMany relation to Userhobbies)
My question now is - how to retrieve all hobby-names (from hobby - table) in my call over (after load('hobbies') ) and is it possible without writting a lot of code?
For better understanding of my idea the result which I want to retrieve:
{"id":"1","username":"jdoe","first_name":"Joe","last_name":"Doe","birth":"
1992-04-11","picture_id":"f3dca65323e876026b409b9ba3d49c56","hobbies":
["golf", "cards", "games", "football"]}
EDIT:
If I try following (I tried with belongsToMany in User and Hobby):
User::with('hobbies')->get()->first()
And I'm getting the whole values from the hobbies - table:
{user-specific data ...
hobbies:[{"id":"1","name":"golf","created_at":"2015-04-07
14:15:02","updated_at":"2015-04-07 14:15:02","pivot":
{"user_id":"1","hobby_id":"1"}},
{"id":"2","name":"cards","created_at":"2015-04-07
14:15:02","updated_at":"2015-04-07 14:15:02","pivot":
{"user_id":"1","hobby_id":"2"}},
{"id":"3","name":"games","created_at":"2015-04-07
14:15:02","updated_at":"2015-04-07 14:15:02","pivot":
{"user_id":"1","hobby_id":"3"}},
{"id":"4","name":"football","created_at":"2015-04-07
14:15:02","updated_at":"2015-04-07 14:15:02","pivot":
{"user_id":"1","hobby_id":"4"}}]}
Same try with ->load('hobbies'). I really don't know how to go on.
To explain it a bit more what I need one could imagine such query as follows:
User::all(['id', 'name'])->load(array('hobbies.id','hobbies.name'))->get();
From my knowledge, I know that it's possible to use a closure to set constraints on the query that performs the load, like so:
User::all()->load(['hobbies' => function($query)
{
$query->select('id', 'name');
}]);
By doing it, when you cast it to array, it will produce a result near to what you want. You can even add 'pivot' to your $hidden property on your Hobby model to hide this information.

CakePHP - Passing an array of record IDs to paginate - is it possible?

Due to having to having to import data from an old non cake app and oddly built database table I need to pass paginate an array of records it is allowed to display - is this possible?
Normally I would reorganise the data into proper relationships etc but due to time scales etc this is not possible.
To give you more info - in my users table I have a field that contains a list of ID's that relate to documents they are allowed to view. The field will contain something like
123,23,45,56,765,122,11.9,71,25
Each ID refers to a document the documents model. I know that normally you would create proper ACOs and AROs and let the ACL/Auth componant handle which users can access what but this isnt an option this time around. So I thought if I could do it via paginate/find it might be an option?
Any help would be really appreciated.
Thanks in advance
You wouldn't pass it a list of IDs, you'd use the IDs in your paginate conditions - something like below.
(Code written off top of my head, so pardon any syntax errors...etc. It should give you the right idea/path at least):
//Controller
$this->loadModel('User');
$this->loadModel('Document');
$user = $this->User->findById($userId);
$documentIds = explode(',', $user['User']['doc_ids']);
$this->paginate = array(
'conditions' => array(
'id' => $documentIds
)
));
$documents = $this->paginate('Document');
When you pass an array as a condtion (eg. 'id'=>$arrayOfIds), it uses MySQLs "IN" - something like:
... WHERE id IN (45, 92, 173)

CakePHP Relationships over more then one Model/Table

I'm new to learning CakePHP. I did the Blog Tutorial and am now trying to add Categories for Posts. I created Category and SubCategory Models and MySQL DB Tables and I related the Models as follows:
Post -> "belongsTo" -> SubCategory -> "belongsTo" -> Category
Post -> Subcategory is working fine and I can resolve the SubCategory Name in the View via:
php echo $post['SubCategory']['name'];
Now: How do I go one step further in the relation and get the Category Name for a Post in the Post View (via the SubCategory)? The following obviously gives me the Category ID, but not it's name:
php echo $post['SubCategory']['category_id'];
Thanks a lot!
Check out the recursive parameter for a model and go for a step 2 (2 levels of depth). This would allow you to use the category if your definition is correct. Keep in mind that it would need to fetch a lot of data and this would affect the overall performance of the site.
You should look into ContainableBehavior, which will help you only grab the results you really need. The first thing I always suggest is changing $recursive = -1 and using Containable. This will also greatly improve the performance of your app because you will be performing less calls for data you don't actually use.
Using your example:
$results = $this->Post->find('all', array(
'contain' => array(
'SubCategory' => array(
'Category'
)
)
));
// in your view foreach loop
echo $post['SubCategory']['Category']['name'];

In CakePHP, is there a better way to select the users name?

I currently have a users table and a posts table. My posts table has a field for user_id, however, I am not sure how I would grab the users name field which is in the users table. I was thinking of using the models afterFind() method and then using SQL to select the data, but there has to be a better way than this. Also, on my view action, I am using the read() function to grab a single post. Would the models afterFind() kick in after it runs read()? If not, is there an equivalent such as afterRead()?
Just make an association of Post belongsTo User, and every regular find/read operation that has a sufficiently high recursive value will automatically fetch the user with each post.
$post = $this->Post->find(...);
echo $post['User']['name'];
you have to go like below :
$this->Cake->findById(7); Cake.id = 7
here , you can you use your user_id instead of 7 like..
Find BY CAKE PHP
$this->Post->bindModel(array('belongsTo'=>'User'));
$post = $this->Post->findById($post_id);
$userName = $post['User']['name'];
Here are errors, I've typed it in eclipse (:

pull Drupal field values with db_query() or db_select()

I've created a content type in Drupal 7 with 5 or 6 fields. Now I want to use a function to query them in a hook_view call back. I thought I would query the node table but all I get back are the nid and title. How do I get back the values for my created fields using the database abstraction API?
Drupal stores the fields in other tables and can automatically join them in. The storage varies depending on how the field is configured so the easiest way to access them is by using an EntityFieldQuery. It'll handle the complexity of joining all your fields in. There's some good examples of how to use it here: http://drupal.org/node/1343708
But if you're working in hook_view, you should already be able access the values, they're loaded into the $node object that's passed in as a parameter. Try running:
debug($node);
In your hook and you should see all the properties.
If you already known the ID of the nodes (nid) you want to load, you should use the node_load_multiple() to load them. This will load the complete need with all fields value. To search the node id, EntityFieldQuery is the recommended way but it has some limitations. You can also use the database API to query the node table for the nid (and revision ID, vid) of your nodes, then load them using node_load_multiple().
Loading a complete load can have performance impacts since it will load way more data than what you need. If this prove to be an issue, you can either try do directly access to field storage tables (if your fields values are stored in your SQL database). The schema of these tables is buld dynamicaly depedning on the fields types, cardinality and other settings. You will have to dig into your database schema to figure it out. And it will probably change as soon as you change something on your fields.
Another solution, is to build stub node entities and to use field_attach_load() with a $options['field_id'] value to only load the value of a specific field. But this require a good knowledge and understanding of the Field API.
See How to use EntityFieldQuery article in Drupal Community Documentation.
Creating A Query
Here is a basic query looking for all articles with a photo that are
tagged as a particular faculty member and published this year. In the
last 5 lines of the code below, the $result variable is populated with
an associative array with the first key being the entity type and the
second key being the entity id (e.g., $result['node'][12322] = partial
node data). Note the $result won't have the 'node' key when it's
empty, thus the check using isset, this is explained here.
Example:
<?php
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'article')
->propertyCondition('status', 1)
->fieldCondition('field_news_types', 'value', 'spotlight', '=')
->fieldCondition('field_photo', 'fid', 'NULL', '!=')
->fieldCondition('field_faculty_tag', 'tid', $value)
->fieldCondition('field_news_publishdate', 'value', $year. '%', 'like')
->fieldOrderBy('field_photo', 'fid', 'DESC')
->range(0, 10)
->addMetaData('account', user_load(1)); // Run the query as user 1.
$result = $query->execute();
if (isset($result['node'])) {
$news_items_nids = array_keys($result['node']);
$news_items = entity_load('node', $news_items_nids);
}
?>
Other resources
EntityFieldQuery on api.drupal.org
Building Energy.gov without Views

Resources