Cakephp habtm saving data - cakephp

Good evening.
Mabye I am blind, but I can't find a solution to this: I have 2 models, Post and Tag with fields post_text and tag_name, where Post habtm Tag.
Now I have form, where I input post_text and couple of tag_names. And I would like to save each of these Tags, keep them unique (so if the Tag is already in DB, don't save it, just get the ID of it), then save the Post and finaly relate the Post with the Tags via posts_tags table.
Now everybody tells me: leave it on Cake, it can do all this work for you! OK, I would love to, but how should my $this->data array look like?
I am trying Tag.tag_name, Post.Tag.tag_name, Post.Tag.0.tag_name, Post.PostsTag.0.tag_name, Tag.Tag.tag_name, Post.PostsTag.Tag.0.tag_name, ...
I am trying save(), saveAll(), ... nothing works. And all the examples on the web (including Cake Book) are working with Tag IDs, not Tag names.
Is there a way (I mean $this->data array form), that I can post to $this->Post->save() or saveAll() and it will do all the magic for me?
Thank you very much.
Josh.T.

Afraid you'll have to write the saveUnique() method yourself, someone may correct me but I don't think cake's automagic goes that far.
You'll basically have to check for each tag, if it exists, get the id(s) into an array - otherwise make it and get the id(s). Then pretty much save that array as a standard habtm with the original post.
It may even be worth using someform of AutoComplete on the add form to get tags that already exist, and then only have to create the one's that don't exist and then saving them + the habtm relationship.

Related

Cakephp - Load a view from another view in a different controller

I've been trying for the past 2 days, how to embed a view from a different controller.
I have two tables (hotels, hotelQuotes), related to each other. The hotels table is linked with a hasmany to the hotelQuotes table, and hotelQuotes with a belongsTo hotels table. Both are linked and working, they both show their related content with no problem.
The hotelQuotes it's pretty much a form, where users fill it out, and then it sends an Email with what the user filled out. Everything is working fine up to this point.
What I want is, when I show the information about the hotel, is to also show that form, I dont want the user to go to another page to fill out the form. So I pretty much want to embed the view of hotelQuotes/Add to the hotel/view.
I doing that using elements, as recommended last night in #cakephp IRC channel, and also here in StackOverFlow at: Embedding view in another view with CakePHP
The problem is that when I do that, the association between the two models gets broken. I mean, the users fill out the form, but I have nowhere to know where that form is coming from, what hotel is referring to. It just doesn't show that piece of vital information for me.
I've been reading about passing variables when using elements at: http://book.cakephp.org/2.0/en/views.html#passing-variables-into-an-element but I don't know how to pass a variable to a form select box. I am using CakePHP 2.5.2.
I hope I explain myself clear here, any input it would be appreciated. See picture below for more info:
http://i.stack.imgur.com/wcG64.jpg
Edit> I just realized that the form is not even submitting when I using elements. Why would that be?
Ok, I just figured out.
The form wasn't even submitting when calling it from elements. So I just passed the action myself like so:
echo $this->Form->create('Hotelquote', array(
'action' => 'add'
));
And now is working.

CakePHP - Prevent model data being save in a saveMany call when certain fields are blank

I have scenario where I have 3 different models data being saved from one form, by means of the saveAll pass through method in CakePHP 2.x
The models on the form are:
Project
ProjectImage
ProjectAttachment
1 and 2 are saving perfectly, but I am having problems with the ProjectAttachment fields. If you look at the following image, the fields in question are at the bottom right, highlighted by a red frame: http://img.skitch.com/20120417-bnarwihc9mqm1b49cjy2bp13cf.jpg
Here is the situation:
I have named the fields as follows: *ProjectAttachment.0.project_id*, ProjectAttachment.0.name .... *ProjectAttachment.6.project_id* etc where the numbers are relative to the already present amount of attachments the user has added, as there is no limit. So if the user has ALREADY added 6 documents, the field would be called ProjectAttachment.7.id and so on. This is because of the naming convention when using the saveAll method.
I have made use of two hidden fields, one to store the user ID, the other to store the project ID.
The problem is that if the user does not fill in the Document Title and select a file to upload, the form fails! If I remove all validation rules, the form no longer fails BUT a blank ProjectAttachment record is inserted.
I suspect the problem may also be that the project_id and user_id fields (that are hidden) already have values in them?
I gave it some thought, and came up with a simple concept: In my controller, before the saveAll call, I would check to see if a blank Document Title field was submitted, and if so, I would completely eliminate the relevant array entry from the $this->request->data['ProjectAttachment'] array, but this did not seem to work.
To clarify, I am not looking for validation rules. If the user decides they only want to upload images and not touch the ProjectAttachment form, them the saveAll operation must not fail, it must simple not attempt to save the blank fields in the form, if this is at all possible.
Any suggestions?
Kind regards,
Simon
Well it seems that the solution was far simpler than I had initially thought! I was partially on the right track, and I had to unset the variable ProjectArray key in the $this->request->data array if I had encountered any blank fields.
I did this as follows:
if(!empty($this->request->data['ProjectAttachment'])){
foreach($this->request->data['ProjectAttachment'] as $key => $value){
if(is_array($value) && array_key_exists('upload_file', $value)){
if($value['upload_file']['name'] == ''){ // Blank document file
unset($this->request->data['ProjectAttachment']);
}
}
}
}
I hope someone finds this somehow useful in some form or another.
Kind regards,
Simon

Customize WordPress comment post query

I am trying to extend the functionality of the comments in a WordPress install. I read allusion to an elusive 'custom comment type' functionality, but could not find any information. Instead, I was thinking that I would add a custom column ' to the 'comments' database table. That's the easy part. What I have no clue how to do is to customize the comments queries for saving, updating and reading the comments to reflect the existence of the new table column. I thought there would be a filter to alter the query, but I cannot find any that would do it... Any ideas?
There isn't really a custom comment type but you can easily and effectively add columns using "comment meta" which is a table of name/value pairs associated where each name/value pair is associated with a given comment using a 'meta_key' (please don't add a column to the SQL database; that's frowned upon in the WordPress developer community.)
Let's assume you wanted to let the user add their Twitter account. This is the code that would save my Twitter account to the comment identified by $comment_ID (prefixing the meta key name with an underscore is a good idea for any meta that you maintain via custom code vs that you let users select the meta key):
update_comment_meta($comment_ID,'_twitter','mikeschinkel');
Then to load the value to display in your template you just call get_comment_meta() (the third parameter means to return a single value, not an array of values):
$twitter = get_comment_meta($comment_ID,'_twitter',true);
Of course without knowing how to hook WordPress to integrate this the above functions would not be a lot of help. There are two hooks you'll need to use, the first being wp_insert_comment which will get called when WordPress saves a comment:
add_action('wp_insert_comment','yoursite_wp_insert_comment',10,2);
function yoursite_wp_insert_comment($comment_ID,$commmentdata) {
$twitter = isset($_GET['twitter']) ? $_GET['twitter'] : false;
update_comment_meta($comment_ID,'_twitter',$twitter);
}
The second one is a bit more complicated; the one that lets you add fields and modify other aspects of the comment form. The 'comment_form_defaults' hook sets the defaults for the comment and let's you add the HTML for a Twitter field (I snagged the format for the HTML from the comment_form() function found in /wp-includes/comment-template.php on line 1511 in WP v3.0.1)
add_filter('comment_form_defaults','yoursite_comment_form_defaults');
function yoursite_comment_form_defaults($defaults) {
$email = $defaults['fields']['email'];
$label = __( 'Twitter' );
$value = isset($_GET['twitter']) ? $_GET['twitter'] : false;
$defaults['fields']['twitter'] =<<<HTML
<p class="comment-form-twitter">
<label for="twitter">{$label}</label>
<input id="twitter" name="twitter" type="text" value="{$value}" size="30" />
</p>
HTML;
return $defaults;
}
And here's what it looks like in action:
This comment form extensibility is new for WordPress 3.0 so by its nature of being new in an open-source project it's probably not going to accommodate all use-cases yet (such as there was no easy way to get a remembered value for the Twitter screen name) but hopefully you'll be able to bend it enough to you will and get what you need and in future released of WordPress the comment form API will almost certainly improve.
Hope this helps.
-Mike
P.S. In future consider posting your question on StackOverflow's sister site WordPress Answers; that's where most of the WordPress enthusiasts hang out, those who can quickly answer questions like this.
I found this useful link related to the topic:
Customizing Comments in WordPress - Functionality and Appearance

How to access relationship data in cakephp?

Im just moving over to cakePHP from Code Igniter and I bet its right in front of me, but i can for the love of god not figure out through the manual nor search the internet, how to access relationship data. For example, say I have two tables BOOKS and AUTHORS. When accessing /books/ and getting a list printed, i can have perhaps ID and Title printed, and author_id. But How do I actually print out the authors first and last name? its in the AUTHORS table?
This, in Code Igniter (using dmz) I simply wrote $book->author->first_name
I just cant seem to find/figure out how its done in cakephp.
(Yes i have the relationship set up in the models)
very grateful for anyone to tell me how, or just point me to where to learn it. Not lazy, been looking, just cant find it.
regards,
Jason
If your relationships are setup correctly, you can
echo $data['Book']['Author']['firstname'];
This should allow you to ouput the stuff.
If the 'Author' data isn't in $books you should make sure your recursion is set properly:
$this->Book->recursive = 1;
Or that you have the 'Author' model contained:
$this->Book->find('all', array('contain' => array('Author'));

Cakephp Tagging - Auto Save new Tags and Tag Relations

I read a lot about tagging in CakePHP but I can't find a "clean" way to save a Post and the Tags to this post. I have all which is necessary the Post Table, Model and Controller, the Tag table, Model and Controller and the posts_tags table. I created the HABTM Associations in the Post and the Tag Model.
If I want to save a new post, I want that CakePHP automagically saves the tags associated to that post, but I can't find the right way for that. In most of the tutorials you have to use a "helper" Function (http://www.jamesfairhurst.co.uk/posts/view/full_cakephp_application_part_5 => "_parse_genres") or something like that, but I thought the deal with CakePHP is it, that this is all done by Cake once you set it up right.
So my question, is there a "clean"-Cake-way to do it, or do I have to use a helper function?
I find it very hard to believe that you didn't find a "proper" way to handle HABTM. There are many, many articles about it. I believe that Cake will save your tags if you set your data array properly. A quick search on The Bakery:
http://bakery.cakephp.org/articles/search/3/HABTM
Will reveal enough. My guess is that you're looking for this:
http://bakery.cakephp.org/articles/view/simple-tagging-behavior
(Note that there is a component which does the same thing, but model behaviour is the right way to go)

Resources