CakePHP does not store the created date on live server - cakephp

I have exactly the same scripts and exactly same databases running on localhost and on live server. The problem I face is that the date for 'created' is not automatically stored.
Here is the controller action:
function add() {
if (!empty($this->data) ) {
$this->Customer->create();
if ($this->Customer->save($this->data)) {
$this->Session->setFlash(__('Customer was saved'), 'positive_notification');
$this->redirect(array('controller'=>'customers', 'action' => 'index'));
} else {
$this->Session->setFlash(__('Customer was not saved. Please try again'), 'negative_notification');
}
}
}
There is also no function for beforeSave.
And here is the database table:
`customers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`company_id` int(11) NOT NULL,
`customer_nr` varchar(20) DEFAULT NULL,
`name` varchar(60) DEFAULT NULL,
`address` varchar(250) DEFAULT NULL,
`email` varchar(100) DEFAULT NULL,
`phone` varchar(18) DEFAULT NULL,
`post_nr` varchar(6) DEFAULT NULL,
`city` varchar(50) DEFAULT NULL,
`color` varchar(7) NOT NULL,
`created` date DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `company_id` (`company_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=113 ;
Any help is much appreciated.

I think you must use:
$this->request->data //instead of $this->data
But if the created is the only field that is not saved try to debug first the $this->data then try this first to see if its really saving a data:
$this->data["Customer"]["created"] = data("Y-m-d"); // temporarily set to current date just to see if it was saving
$this->Customer->save($this->data)
Then checked if its added on your database. If yes, then you must update your $this->data, it may contain incorrect values or incorrect format of date.

The date is not automatically updating, because you set created to be date instead of datetime.
As stated on "Saving Your Data"
By defining a created and/or modified field in your database table as datetime fields (default null), CakePHP will recognize those fields and populate them automatically whenever a record is created or saved to the database (unless the data being saved already contains a value for these fields).
I hope this will solve your problem.

Related

CakePHP 3 doesn't submit the forgeign key fields value

I have the following 2 tables, and the default classes generated from
bin/cake bake all clients
bin/cake bake all clients_address
When I try and add an address, setting the "client_id" to 1, I get the following error.
Error: SQLSTATE[HY000]: General error: 1364 Field 'client_id' doesn't have a default value
If you are using SQL keywords as table column names, you can enable identifier quoting for your database connection in config/app.php.
SQL Query:
INSERT INTO clients_address (address_line_1, address_line_2, address_line_3, town, county, postcode, email, tel, contact_name, default_address) VALUES (:c0, :c1, :c2, :c3, :c4, :c5, :c6, :c7, :c8, :c9)
Is there some extra code needed to get the client_id to be submitted?
CREATE TABLE `clients` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `clients_address` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`address_line_1` varchar(30) NOT NULL,
`address_line_2` varchar(30) NOT NULL,
`address_line_3` varchar(30) NOT NULL,
`town` varchar(30) NOT NULL,
`county` varchar(30) NOT NULL,
`postcode` varchar(8) NOT NULL,
`email` varchar(50) NOT NULL,
`tel` varchar(13) NOT NULL,
`contact_name` varchar(40) NOT NULL,
`client_id` int(11) NOT NULL,
`default_address` BOOLEAN NOT NULL DEFAULT 0,
FOREIGN KEY (client_id) REFERENCES clients(id),
PRIMARY KEY (`id`)
);
INSERT INTO `clients` (`id`, `name`) VALUES (1, 'First Client');
In your clients_address Table schema client_id int(11) NOT NULL, set. But when you insert a Address then you don't set value against client_id and client_id can't be NULL
Probably solutions
Set client_id in Address insert query
In your table schema client_id allow NULL or set a default value
You need to be sure that "client_id" is sent. Check with your Debug Kit bar on History, select the POST request, and then go to Sql log.
There must be a query like this:
INSERT INTO clients_address (
client_id, address, modified
)
VALUES
(
61, 'my address', "123..."
)
If not maybe something is wrong with your Form.
Your query must be something like this:
INSERT INTO clients_address (address_line_1, ..., contact_name, CLIENT_ID, default_address)
VALUES (:c0, :c1, :c2, :c3, :c4, :c5, :c6, :c7, :c8, :c9)
If you are adding addresses standalone (addresses controller add method), you must stipulate "client_id" manually on Form, or from a hidden field based on a parameter, with Cake bake it will make a list of Clients on Add and Edit methods.
If you are adding the address from Client Form as an association, on CakePHP docs are some good examples https://book.cakephp.org/3.0/en/views/helpers/form.html#creating-inputs-for-associated-data

CakePHP Find function

i am using the following statement.
$users = $this->User->find('all');
But in the database there are only 174 rows. but the query is returning 200 rows.
When i out put the content i see that a lot of rows are repeated.
Any idea why this behavior in cakephp ?
Structure
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(255) NOT NULL,
`last_name` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`username` varchar(255) NOT NULL,
`password` varchar(40) NOT NULL,
`display_photo` varchar(255) DEFAULT NULL,
`subscription_plan_id` int(11) unsigned NOT NULL,
`company_id` int(11) NOT NULL,
`status` tinyint(2) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=177 ;
by trying to debug using this statment
echo $users = $this->User->find('count');
i get 200 itself.
Models: http://pastebin.com/p4bFPiUz
The query you are running does not nearly match the queries that CakePHP will actually execute. CakePHP will also perform all the required joins to get related data. So, this is not really a proper comparison that you are doing.
Some of your relations might return double results, like User -> CompanyA, but there could also be a User -> CompanyB relation, which would trigger 2 result rows for 1 single user.
To see the queries that Cake actually executes, use the getLog method on your datasource, like:
$ds = $this->User->getDataSource();
$log = $ds->getLog();
debug($log);
Or use something like DebugKit to get a panel with all the queries by default (when in debug mode).

How to get permissions in cakePHP

First, sorry for my language skills, I am not used to writing in English. ;)
I'm trying to develop my first cakePHP application.
What I'm trying to do:
Users are in groups and groups have
access to different locations.
Users can add reservations for this
locations.
So my main problem is to find the best way to get the permissions of the user:
The user should only see the locations on which he has access.
If a user tries to add a reservation for a location, I have to check his permission for this location.
etc.
I also have moderators and admins, but I think this is a similar problem.
So, how can I do this properly? The ACL doesn't seem to be the right way - in most tutorials it controls the access to actions, not to db-rows.
What my Database looks like:
I have a user table and use the AuthComponent to manage the authentication. This works fine.
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(64) NOT NULL,
`password` varchar(64) NOT NULL,
`enabled` tinyint(1) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`)
)
I have a groups table for usergroups.
CREATE TABLE IF NOT EXISTS `groups` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(64) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
)
CREATE TABLE IF NOT EXISTS `groups_users` (
`group_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
UNIQUE KEY `group_id` (`group_id`,`user_id`)
)
And I have my locations.
CREATE TABLE IF NOT EXISTS `locations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(64) NOT NULL,
`adress` text NOT NULL,
`description` text,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
)
The table contains the permissions, which group has access to which location.
CREATE TABLE IF NOT EXISTS `groups_locations` (
`group_id` int(11) NOT NULL,
`location_id` int(11) NOT NULL,
UNIQUE KEY `group_id` (`group_id`,`location_id`)
)
Of course the reservations table:
CREATE TABLE IF NOT EXISTS `reservations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`location_id` int(11) NOT NULL,
`start` date NOT NULL,
`end` date NOT NULL,
`user_id` int(11) NOT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
)
THX
Are you sure that you need the groups_users table? Wouldn't each user only be able to belong to one group?
You will be able to accomplish this much easier if you just bring the group id into the users table as a foreign key
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(64) NOT NULL,
`password` varchar(64) NOT NULL,
`enabled` tinyint(1) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
`group_id` int(11) NOT NULLL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`)
)
Then you can send to the view whether or not the user should be able to see certain information...
in your app_controller.php add the following
function beforeFilter(){
$this->set('users_role', $this->Auth->user('group_id'));
}
Now you will have a variable accessable by your view which will be $users_role... then you can perform the following in your view.
<?php if($users_role == 1 ): ?>
//show records available to admins
<?php elseif ($users_role == 2): ?>
//show records available to logged in users
<?php else : ?>
//show records for all users
<?php endif; ?>
Maybe I have a solution - I could use some feedback:
After the user logged in, I save the permissions in his Session-Variables:
function login() {
if($user = $this->Auth->user()) {
$this->User->unbindModel(array(
'hasMany' => array('Reservation'),
));
$user = $this->User->find('first', array('conditions' => array('id' => $user['User']['id']), 'recursive' => 2));
$this->Session->write('Auth.User.Group', $user['Group']);
}
I'm not sure how secure this solution is and permission changes only affects after logout, but it seems to work fine.

CakePHP Bake association problem

I have only two tables in my database with a one-to-many relationship between them (user hasMany messages) and am trying to get basic CRUD functionality going. Bake detects the associations correctly and specifies them correctly inside the model classes, but in controllers and views it looks like Cake doesn't know anything about those associations -- I don't even get a select tag for user_id when I go add a new message. Has anyone come across this problem before? What can I be doing wrong?
Table structure appears to be fine:
CREATE TABLE users (
id int(11) NOT NULL AUTO_INCREMENT,
username varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
email varchar(255) NOT NULL,
created datetime NOT NULL,
modified datetime NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `messages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`content` varchar(255) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
If you're using the console to bake your MVC files you could try that.
First bake the model files. Then bake the controller files using scaffold.
Then bake the view files.
Finally go back and bake the controller files without scaffold.
This should get you all basic CRUD functionality with all the associations you may have.
Hope that helps ...

Can I have additional fields on the users table in CakePHP & still use the built-in auth methods?

I'm using cakePHP and I want to add a First and Last name column to the Users table, but when I pass through the field values firstname & lastname the columns are always left null, while the default fields are populate fine.
Is it possible to do this or do I need to have a second table to store these values?
Update code:
Registration form
<?php
$session->flash('register');
echo $form->create('User', array('action' => 'register/'));
echo '<h3>Register</h3>';
echo $form->input('firstname', array('label'=>'First Name'));
echo $form->input('lastname', array('label'=>'Last Name'));
echo $form->input('username');
echo $form->input('email');
echo '<input class="submitimg" type="image" src="' . $basepath . 'img/btn_submit.gif" alt="Submit" />';
echo $form->end();
?>
Register action in user_controller.php
function register() {
if (!empty($this->data)) {
$password = $this->str_makerand(8,10);
$this->data['User']['password'] = $this->Auth->password($password);
$this->User->create();
$result = $this->User->save($this->data);
if ($result) {
$this->Session->setFlash('Registration complete, an email will be sent with your password', 'default', array(), 'register');
$this->sendNewUserMail($this->data['User']['username'], $this->data['User']['email'], $password);
} else {
$this->Session->setFlash('That username or email address is already taken, please try again', 'default', array(), 'register');
}
}
$this->redirect(array('controller' => 'properties', 'action' => 'index'));
}
MySQL users table:
CREATE TABLE users (
id int(11) NOT NULL AUTO_INCREMENT,
username char(50) DEFAULT NULL,
firstname varchar(100) NOT NULL,
lastname varchar(100) NOT NULL,
password char(50) DEFAULT NULL,
email varchar(100) NOT NULL,
created datetime NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY email (email),
UNIQUE KEY username (username)
)
Thanks for your help
You can definitely have additional fields on your users table. The Auth component will just authorize against your username and password fields in that table. In fact, if you read up on the Auth component's attributes you'll find that you can set which fields Cake will use as the user/pass fields.
Sounds like your problem is a bug. Please post some code and database schema and I'll take a look to help you further.
In cases like these it's considered best practice to have a separate table linked to the user table that includes all the extra information you want to keep.
This is my users table:
CREATE TABLE `cake_users` (
`id` int(11) unsigned NOT NULL auto_increment,
`username` varchar(100) default NULL,
`password` varchar(100) default NULL,
`email` varchar(150) default NULL,
`firstname` varchar(60) default NULL,
`lastname` varchar(60) default NULL,
`priv` int(4) default '0',
PRIMARY KEY (`id`)
);
I don't have public user registration, but I can create users with the additional fields. This is the code I use in the controller:
function admin_add() {
if (!empty($this->data)) {
$this->User->create();
$this->set('password',$this->Auth->password($this->data['User']['password']));
if ($this->User->save($this->data)) {
$this->Session->setFlash(__('The User has been saved', true));
$this->redirect(array('action'=>'index'));
} else {
$this->Session->setFlash(__('The User could not be saved. Please, try again.', true));
}
}
}
Extra fields are, or course, possible and normal. There is probably a hidden bug somewhere in your code.
Did you try debugging/outputting $this->data after a post? Are your firstname/lastname values showing in the array? Do you have a column whitelist/blacklist in your model which prevents those fields to be saved? How do the input fields look in the output HTML? They are supposed to be named as data[User][firstname] and if they are not, something is terribly wrong..

Resources