I am still fairly new to CakePHP, though I like to think I have some basic understanding.
I have made a basic blog, based on an 'articles' table and bake all, piece of cake so far ;D. Now I've added a 'comments' table. 'articles' hasMany 'comments' and 'comments' belongsTo 'articles'. I again baked all for both tables and edited the 'view' action in ArticlesController.php and Articles/view.ctp to display all the comments of an article. No issues yet.
Now I'd like to be able to add a comment on the 'view' page of an article, much like you can comment on this forum. So I've added an Html->Form to view.ctp and copied some parts from the comment's add() to the article's view(). Article's view action:
public function view($id = null) {
$article = $this->Articles->get($id, [
'contain' => ['Comments']
]);
// Part from the add-action from Comments
$comment = $this->Comments->newEntity();
if ($this->request->is('post')) {
$comment = $this->Comments->patchEntity($comment, $this->request->data);
if ($this->Comments->save($comment)) {
$this->Flash->success(__('The comment has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The comment could not be saved. Please, try again.'));
}
}
// Set the selected article
$this->set('article', $article);
$this->set('_serialize', ['article']);
}
A part from Articles/view.ctp :
<?php foreach ($article->comments as $comment) : ?>
<h5><?= $comment->author ?></h5>
<p><?= $comment->body ?></p>
<?php endforeach; ?>
<b>Add comment</b>
<?= $this->Form->create($comment) ?>
<?php
echo $this->Form->input('comment.author');
echo $this->Form->input('comment.body');
?>
<?= $this->Form->button(__('Submit Comment')) ?>
<?= $this->Form->end() ?>
But this gives me a fatal error, :
Error: Call to a member function newEntity() on boolean File
C:\xampp\htdocs\blog_simple\src\Controller\ArticlesController.php
Line: 45
Any suggestions on how to accomplish what I'm looking for?
Error: Call to a member function newEntity() on boolean File
C:\xampp\htdocs\blog_simple\src\Controller\ArticlesController.php
Line: 45
Because you are in Articles Controller and you are trying Comments related functions (without Loading Model).
You have two option.
If you have correct relationship set up, then append Articles to calls like,
$comment = $this->Comments->newEntity();
to
$comment = $this->Articles->Comments->newEntity();
Similarly do for all the comments PatchEntity and Save function.
Add
$this->loadModel('Comments');
before calling Comments related functions. No need to append Articles like mentioned in previous point. Because, we are loading model.
Try which one you prefer. Good luck!
Related
I'm new when it comes to work with CakePHP. I'm facing a problem that is bothering me since i started doing it. I got a form with an input and when a person types in what he/she wants (it is a classified website where you can search for something that you'd like to buy eg. a blue pen) it shows the page that refers to the desired object. For example. if i type in 'blue pen', it retrieves all the data that i have in my database related to the blue pen.
Hope you can help me, there is my code:
index.ctp
<?php
echo $this->Form->create('Location', array('type' => 'get'));
echo $this->Form->input('Find');
echo $this->Form->end();
?>
and my ArticlesController
public function search() {
$obj = '';
if (!empty($this->data)) {
$obj = $this->data['Location']['Procurar'];
$opts = array(
'conditions' => array('Location.Procurar' => $obj)
);
}
$this->set('obj', $obj); // so the keyword is saved. Can also get it via $this->data
}
I'm trying to make some kind of custom calendar system in CakePHP. What I'm trying to do is add an agendascreen_activity Model (of which all the fields already get saved correctly) and an associated model agendascreen_no_repetitions which has an id time, date and a FK pointing to the activity.
My problem is that the date and time fields don't get saved properly
here is my code so far:
In my add.ctp file:
<?= $this->Form->input('agendascreen_no_repetitions.date', ['type' => 'date']) ?>
<?= $this->Form->input('agendascreen_no_repetitions.time', ['type' => 'time']) ?>
In my controller:
public function add()
{
$agendascreenActivity = $this->AgendascreenActivities->newEntity();
if ($this->request->is('post')) {
$agendascreenActivity = $this->AgendascreenActivities->patchEntity($agendascreenActivity, $this->request->data);
if ($this->AgendascreenActivities->save($agendascreenActivity)) {
$this->Flash->success(__('The agendascreen activity has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The agendascreen activity could not be saved. Please, try again.'));
}
}
$agendascreens = $this->AgendascreenActivities->Agendascreens->find('list', ['limit' => 200]);
$this->set(compact('agendascreenActivity', 'agendascreens'));
$this->set('_serialize', ['agendascreenActivity']);
}
The datatypes of the fields of the MySql DB are DATE and TIME
In the CakePHP debugger I can see that all the data is being sent correctly in the POST().
However when I look at the result, it adds the agendascreen_no_repetitions record two times with null as value for the date and the time.
After ndm's comment I checked if the data was being patched to the entity correctly.
I noticed that the time and date contents were directly under the agendascreen_no_repetitions object. instead of under time and date.
I tried the following:
<?= $this->Form->input('agendascreen_no_repetitions[0].date', ['type' => 'date']) ?>
<?= $this->Form->input('agendascreen_no_repetitions[0].time', ['type' => 'time']) ?>
which resulted in the following:
I'm working with cakephp for project development. I wrote a function to get data from the database and do a summation.I have created a table called user with height and weight in it. I want to retrieve that data,add them, and to return that. Here is the function I wrote.
public function calculate()
{
$Height=$this->set('user',$this->User->find('first'));
$Weight=$this->set('user1',$this->User->find('first'));
$sum=($Height+$Weight);
$this->set('SUM',$sum);
}
In the view I wrote the following code.
<div class="page-content">
<?php echo $user['User']['weight']; ?>
<?php echo $user1['User']['height']; ?>
<?php echo $SUM ?>
</div
Height and weight values are getting displayed. But the sum value is displayed as zero. Please help me to fix this.
I found a better way to do the above calculation. I used the following code in the controller.
public function calculate($id=null)
{
if (!$this->User->exists($id)) {
throw new NotFoundException(__('Invalid user'));
}
$this->set('user1',$this->User->find('first', array('fields' => ('height'),'conditions' => array('User.id' =>$id))));
$this->set('user',$this->User->find('first', array('fields' => ('weight'),'conditions' => array('User.id' =>$id))));
}
My view looks similar to the one mentioned above. This works fine with me...
First you need get the field from find. (You can use find condition to filter de user id for example).
$user = $this->User->find('first', array(
'conditions' => array('User.id' => $id),
'fields' => array('User.height', 'User.weight') // fields from your DB
));
So, you can do a pr($user) to see the data and know what use.
After do the sum and set to the view. Cakephp Set
I'm trying to use Elements in Cakephp 2.0 without luck. I have a model named Post, a controller named Posts and various views. In the layout I would like to include (for every page/view) a box with the most recent news (say 2).
So I created the element dok-posts.ctp
<?php $posts = $this->requestAction('posts/recentnews'); ?>
<?php foreach($posts as $post): ?>
<div class="Post">
....
In my PostsController I added the function recentnews()
public function recentnews(){
$posts = $this->Post->find('all',array('order' => 'Post.created DESC','limit' => 2));
if ($this->request->is('requested')) {
return $posts;
} else {
$this->set('posts', $posts);
}
}
In my layout, default.ctp I call my element
<?php echo $this->element('dok-posts'); ?>
The problem is that I get this message
Invalid argument supplied for foreach() [APP\View\Elements\dok-posts.ctp, line 9]
Debugging in dok-posts.php, right after the $this->requestAction, gives me an empty line. It seems that the recentnews function is not returning anything (debugging in the function returns an array with the posts found). Can anyone please tell me what am I doing wrong?
Since you found out that the action is actually called,
$posts = $this->requestAction('posts/recentnews');
is working correctly. Here, for clarity and extended configuration options (for later changes to the code), I suggest you to use a Router array instead of an URL
$posts = $this -> requestAction(array(
'controller' => 'posts',
'action' => 'recentnews'
));
Now to your actual problem...
Since you say, it always goes into the else branch,
$this->request->is('requested')
might not work as expected. Try this (it works perfect for me):
if (!empty($this -> request -> params['requested'])) {
return $posts;
}
In your app controller create beforefilter and getNewsElement function.
public function beforeFilter() {
parent::beforeFilter();
$data = $this->getNewsElement();
$this->set('posts',$data);
}
function getNewsElement(){
# Put Post model in uses
$posts = $this->Post->find('all',array('order' => 'Post.created DESC','limit' => 2));
return $posts;
}
dok-posts.ctp
#Remove <?php $posts = $this->requestAction('posts/recentnews'); ?>
<?php foreach($posts as $post): ?>
<div class="Post">
....
In PostsController
public function recentnews(){
$posts = $this->getNewsElement();
$this->set('posts', $posts);
}
This will solve your problem!
Try
<?php $posts = $this->requestAction('/posts/recentnews'); ?>
(note the leading forward slash)
I have followed the example in the Cakephp's guide. From the moment it does not passes the if statement it seems that there is a problem with the control.
$this->request->is('requested')
So I removed the
is->('requested')
adding
->params['requested']
and it works.
Thank you all for your help (especially wnstnsmth for the solution).
Try this
<?php $this->requestAction('/controllerName/functionName');?>
My objective is to display records for a related child model (once removed) in the view. I understand that setting the recursive value to '1' returns the current model, its owner(s), plus their associated models.
What I don't know how to do is display this in the view.
My approach has been to create a varialable in the controller holding the value of the associated model ID, but that hasn't work.
*I should also mention that I'm using a sluggable behavior for tournaments, so it's not $id that is used but $slug.
Here are the model view controller details:
Model
tournament - has many tournamentDetails
tournamentDetails - has many updates
updates - belongs to tournamentDetails
tournaments controller
action = view
class TournamentsController extends AppController
function view($slug = null) {
if (!$slug) {
$this->Session->setFlash(__('Invalid Tournament.', true));
$this->redirect(array('action'=>'index'));
}
$this->Tournament->recursive = 1;
$tournament = $this->Tournament->findBySlug($slug);
$updates = $this->Tournament->TournamentDetail->Update->find('all', array('conditions'=>array('update.tournament_detail_id' => $this->data['tournament_details'] ['id'] )) );
$this->set(compact('tournament','updates' ));
Tournament view. This is display the 'tournament details' and (ideally) related tournament detail 'updates'
<h2><?php echo $tournament['Tournament']['name']; ?></h2>
<?php foreach ($tournament['TournamentDetail'] as $tournamentDetail): ?>
<h1><?php echo $tournamentDetail ['title']; ?></h1>
<p><?php echo $tournamentDetail ['body']; ?></p>
<?php endforeach; ?>
<?php foreach ($updates['Update'] as $update): ?>
<h4>Update: <?php echo $update ['date']; ?></h4>
<p> <?php echo $update ['Update'] ['title']; ?></p>
<p><?php echo $update ['Update'] ['body']; ?></p>
<?php endforeach; ?>
when I debug $updates, this is all I see:
Array
(
)
I don't know what I'm doing wrong here.
Is it not correct to construct the find conditions by using:
('conditions'=>array('update.tournament_detail_id' => $this->data['tournament_details'] ['id'] )
Thanks for the help.
Paul
You can use the Containable Behavior to specify in detail what fields you want to obtain from associated models, associated models to associated models and so on. Then you will find all data inside the array $tournament, like in the examples in the link.
EDIT (in response the OP comment). I think that the problem may be using the magic findBy method. You would need to substitute that with the standard find, like in this example
$tournament = $this->Tournament->find('first', array(
'conditions' => array(
'slug' => $slug
),
'contain' => array(//Put here the settings for Containable
)
));