I have a ProductsController with an add view that as an autocomplete field ('brand_name') on it where the user can enter a brand name.
In my handler I want to check if the brand name already exists in the database, the brand_id should be set on the product. If it does not exists in the database, a new Brand should be created and inserted in the database.
The code beneath is simplified:
app/Model/Product.php
class Product extends AppModel {
public $belongsTo = array('Brand');
}
app/Controller/ProductsController.php
class ProductsController extends AppController {
public $helpers = array('Html', 'Form', 'Session');
public $components = array('Session');
public function add() {
if ($this->request->is('post')) {
$this->Product->create();
$brand = $this->Product->Brand->find(
'first',
array(
'conditions' => array(
'Brand.name' => $this->request->data['Product']['brand_name']
)
)
);
if($brand)
{
$this->request->data['Product']['brand_id'] = intval($brand['Brand']['id']);
}
else
{
// Add new brand
//$this->Product->Brand->create();
$this->Product->Brand->name = $this->request->data['Product']['brand_name'];
}
if ($this->Product->saveAll($this->request->data)) {
$this->Session->setFlash(__('The product has been saved.'));
//$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('Unable to add the product.'));
}
}
}
}
Everything works fine, except for creating and inserting the new Brand object. How do I create this object in code?
I'm brand new to CakePHP so if my approach is wrong, please let me know.
I've fixed this by adding a new value to the $this->request->data array, like this:
if($brand)
{
$this->request->data['Product']['brand_id'] = intval($brand['Brand']['id']);
}
else
{
$this->request->data['Brand']['name'] = $this->request->data['Product']['brand_name'];
}
Related
I made a blog and I can leave comments to my articles, then I made an Approve button, need to make the approve function.
I need to make it to work. I just can't, no matter what I try. I want to be able to approve or not a comment before it's posted. I have tried everything I could think of.
<?php
namespace App\Controller;
class CommentsController extends AppController
{
public function index()
{
$comments = $this->Comments->find('all');
$this->set(compact('comments'));
}
public function view($id = null)
{
$comment = $this->Comments->get($id);
$this->set(compact('comment'));
}
public function add()
{
$comment = $this->Comments->newEntity();
if ($this->request->is('post')) {
$comment = $this->Comments->patchEntity($comment, $this->request->data);
$comment->user_id = $this->Auth->user('id');
$comment->aproved = 0;
$comment->article_id = $this->request->data['article_id'];
if ($this->Comments->save($comment)) {
$this->Flash->success(__('Your comment has been saved.'));
return $this->redirect(['controller' => 'Articles', 'action' => 'view', $comment->article_id]);
}
$this->Flash->error(__('Unable to add your comment.'));
}
$this->set('comment', $comment);
}
public function aprove()
{
}
}
Try this
Your link should look like this:
$this->Html->link('approve', array('controller' => 'your-controller', 'action' => 'aprove', $comment_id, $value['Comment']['aproved']));
and your controller function is:
public function aprove($comment_id, $approve_value)
{
if(isset($comment_id) && !empty($comment_id)){
$approve = $this->Comments->find('first',array('conditions'=>array('id'=>$comment_id),'fields'=>array('Comment.id, Comment.approve')));
if(!empty($approve)){
$this->Comments->id = $approve['Comment']['id'];
$this->Comments->saveField('aproved', $approve_value);
}
}
}
I have a User Model and a Boarder Model, Not every User is a Boarder but Every Boarder is a User.
User model
class User extends AppModel
{
public $primaryKey = "user_id";
public $hasMany = 'Boarder';
}
Boarder model
class Boarder extends AppModel
{
public $belongsTo = 'User';
}
add.ctp of my Boarders View
<?php
echo $this->Form->create('Boarder', array('role' => 'form', 'novalidate' => true));
echo $this->Form->input('user_name');
echo $this->Form->input('bdr_home_address');
echo $this->Form->end();
?>
So during submit, add function in controller will now receive an array something like this
Array
(
[Boarder] => Array
(
[user_name] => 'John',
[bdr_home_address] => 'Some Street, Some City'
)
)
[user_name] will be saved in Users Model while [bdr_home_address] will be saved in Boarders model. as indicated in my $this->Form->create the request will be directed to BoardersController, action add. So how will I be able to save this?
BoardersController
class BoardersController extends AppController
{
public function add()
{
}
}
If every Boarder is a User, the Boarder table should include a user_id field.
The add.ctp form can look like
<?php
echo $this->Form->create('Boarder', array('role' => 'form', 'novalidate' => true));
echo $this->Form->input('User.username');
echo $this->Form->input('Boarder.home_address');
echo $this->Form->submit();
echo $this->Form->end();
?>
The add function from the controller is:
public function add()
{
if ($this->request->is('post')) {
debug($this->request->data);
if ($this->Boarder->saveAssociated($this->request->data)) {
// saved
} else {
// not saved
}
}
}
I have the following model:
class Person
{
public $name;
function __Construct( $name )
{
$this->name = $name;
}
}
I have the following controller:
class NavigationController extends Controller
{
public function indexAction()
{
$people = array(
new Person("James"),
new Person("Bob")
);
return $this->render('FrameworkBundle:Navigation:index.html.php', $people);
}
}
How do I get access to the model array in the view. Is there a way to access the model directly or do I have to assign a property like so:?
class NavigationController extends Controller
{
public function indexAction()
{
$people = array(
new Person("James"),
new Person("Bob")
);
return $this->render('FrameworkBundle:Navigation:index.html.php', array( "model" => $people ) );
}
}
View:
<?php
foreach( $model as $person )
{
echo $person->title;
}
?>
The problem with the above will be that it can be changed by a user to
return $this->render( 'FrameworkBundle:Navigation:index.html.php', array( "marybloomingpoppin" => $people ) );
With the example view you used, you already had the correct implementation:
class NavigationController extends Controller
{
public function indexAction()
{
$people = array(
new Person("James"),
new Person("Bob")
);
return $this->render('FrameworkBundle:Navigation:index.html.php', array( "model" => $people ) );
}
}
You mentioned the concern that somebody could change the assignment in the controller, but this is something you always have if somebody changes the name of a variable only in one place and not in all. So I don't think this is an issue.
i have a controller in cakephp named AdminsController. With the addadmin($id) function,as you can see,i try to update a user's role to 'admin',finding him in the database using his user id (the variable $id).
class AdminsController extends AppController {
public $helpers = array('Html','Form');
var $uses = array('Admin', 'User');
public function index() {
if(!($this->Auth->user('username') && $this->Auth->user('role') == 'admin')) {
throw new NotFoundException(__('Unauthorized access.Please login first.'));
$this->redirect(array('controller' => 'users','action' => 'login'));
}
}
public function addAdmin($id) {
$this->loadModel('User');
$this->User->id = $id;
$this->User->set('role','admin');
$this->User->save();
}
}
But this code does not work,though many other cakephp users in stackoverflow have told me that this is the way to do this..
Do you knwo what maybe goes wrong or you can help me in any case?
thank you in advance!
Try this:
public function addAdmin($id) {
$this->loadModel('User');
$this->User->id = $id;
$this->User->saveField('role','admin');
}
If that doesn't work, you are not getting the right ID.
Is 'role' is a field in your users table? And is 'admin' a valid value for that field? If so this should work:
$this->User->id = $id;
$this->User->saveField('role', 'admin');
See here. Hope this helps.
I've two Models:
class Post extends AppModel {
var $name = 'Post';
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
)
);
}
and
class User extends AppModel {
var $name = 'User';
var $hasMany = 'Post';
}
Now I'm having a problem with a query in the PostsController. I've an add() function and the view add.ctp which is basically a form. Now I would like to show some User information in that form.
class PostsController extends AppController {
var $name = 'Posts';
var $helper = array('Html', 'Form');
var $uses = array('User');
public function index() {
$this->set('posts', $this->Post->find('all'));
}
function add() {
$user_id = 1;
$this->set('user', $this->User->findById($user_id));
if ($this->request->is('post')) {
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash('Your post has been saved.');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Unable to add your post.');
}
}
}
}
But now the add-view-page shows that actually two queries where triggered. So if I print_r($user) within the add-view I'm getting an array with two arrays. One for a Post with user_id = 1 and one for the actual User with id = 1. But I would like to get only the User id = 1.
Try setting recursive to false on the User model before calling findById, so you won't get any data from associated models. Like this:
function add() {
$user_id = 1;
$this->User->recursive = false;
$this->set('user', $this->User->findById($user_id));
if ($this->request->is('post')) {
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash('Your post has been saved.');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Unable to add your post.');
}
}
}