How do I make it so when a user deletes something it still exists, but is just hidden from everyone? - cakephp

Currently when a user deletes an item, it gets properly deleted, but due to the structure of my database and wanting to preserve data I would rather simply hide it from everyone except the admin but have it appear deleted to the user.
Here is an example of how I am currently deleting items from the View:
<?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $serial['Serial']['id']), null, __('Are you sure you want to delete # %s?', $serial['Serial']['id'])); ?>
And here is the delete function that is called in the Controller:
public function delete($id = null) {
$this->Serial->id = $id;
if (!$this->Serial->exists()) {
throw new NotFoundException(__('Invalid serial'));
}
$this->request->onlyAllow('post', 'delete');
if ($this->Serial->delete()) {
$this->Session->setFlash(__('The serial has been deleted.'));
} else {
$this->Session->setFlash(__('The serial could not be deleted. Please, try again.'));
}
return $this->redirect(array('action' => 'index'));
}
}

How do I make it so when a user deletes something it still exists, but is just hidden from everyone?
By not deleting, but just flagging it as deleted (using an extra deleted column or similar) and excluding such flagged records from your find operations (using for example the Model::beforeFind() callback to inject a condition like deleted = 0).
Just search for "soft delete", and you'll find ready made behaviors such as
CakeDC Utils - SoftDelete
dereuromark CakePHP Tools - SoftDelete

Use database flag like deleted as enum which can be 1 Or 0 , So If you click on delete , it updates as 1 , Like soft delete.
So in model , use condition to fetch only recs with deleted status as 0 .
Or in controller use find query with condition to fetch only recs with deleted status as 0 .

Related

CakePhp save changes only in middle table

Here is the problem what I have
I have 3 tables m:n
Users -> addresses_users -> Addresses
During adding new user I am selecting from dropdown X Addresses and after I click save I have to save new user data (new user in Users table), make mapping in addresses_user table and Addresses table shouldnt be changed, cos I have already those addresses in DB.
So, if i use code like this
input in ctp with
name="addresses[]"
In controller
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->
if ($this->Users->save($user)) {
$this->Flash->success(__('The user has been saved.'));
return $this->redirect(['controller' => 'users', 'action' => 'view/' . $user->id]);
} else {
$this->Flash->error(__('The user could not be saved. Please, try again.'));
}
}
Cakephph makes mapping automatically and want to save new user, mapping and information about addresses.
Is there way to make this automatically with cakephp that he saves new user and make mapping or I should use another input name (that cakephp doesnt make patch with addresses) and after save make foreach with all addresses_id and save values direct to addresses_users table?
Or there is better ideas?

Add a user in Cakephp

There is a problem when I write an add() function for UsersController.
public function add() {
if ($this->request->is('post')) {
$this->request->data['User']['book_id'] = $this->Book('id');
if ($this->User->saveAssociated($this->request->data)){
$this->request->data['User']['book_id'] = "ff";
$this->Session->setFlash(__('Save User'));
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('User Error.'));
}
}
If I add a User I want to save the book ID in my User book_id.
Anyone know how to deal with this problem? Thanks!
When you're adding a new user, does he get to select a book from a drop down(in the form)? If so, $this->request->data['User']['book_id'] will already contain the Book id.
There's no need to explicitly write $this->request->data['User']['book_id'] = $this->Book('id'); like you have done.
The way I see it, the add.ctp view file should contain a select box containing a list of all books which the user can select. On selecting one of those and submitting the form, $this->request->data['User']['book_id'] will automatically store the book_id, without having to write anything in the controller.
Please specify the add.ctp form fields so that I can assist you better.
Thanks!

Weird problems while getting ID just after saving data

I have different models which are an extension of another one.
classes (SubModel1, SubModel2, ..,6) extends -> HighModel extends -> Appmodel
Everytime I save data in each submodel I call a function in my HighModel to save the id of the just saved SubModel. It works perfectly with five SubModels, but in one the id is always: ($shouldBeThisId - 1)in both add and edit functions.... o_O
Here's my add function:
public function add() {
if ($this->request->is('post')) {
$this->M18Tab->create();
if ($this->M18Tab->save($this->request->data)) {
$data = $this->M18Tab->findById($this->M18Tab->id); //<---problem's here
if($this->M18Tab->M18Model->saveVersion($data)){
$this->Session->setFlash(__('The m18 tab has been saved'));
$this->redirect(array('action' => 'view', $this->M18Tab->id));
} else {
$this->Session->setFlash(__('Error with versioning system'));
}
} else {
$this->Session->setFlash(__('The m18 tab could not be saved. Please, try again.'));
}
}
//view variables
}
ok. so after saving I recall the "just saved data" and pass it to $this->SubModel->HighModel->saveVersion($data). and the weird thing is that if I try to force the id to find:
$data = $this->M18Tab->findById(33);
it'll still find the id preceding the just inserted one :0.
what could this be caused by? the code is the same for all 6 models and in only one I have this issue..
This is more of a comment/suggestion than an answer, but anyway...
If you're adding a new record, after calling save, you can get it's ID via:
$this->MyModel->getInsertId();
See that method in the cookbook. I know the id should also be available at $this->MyModel->id, but since it's not working in this case, you might want to try:
$data = $this->M18Tab->findById($this->M18Tab->getInsertId());

Creating muliple users in a loop from array

How does one go about creating multiple new users, say in a loop, from an array in a different controller?
I have an issue where attempting to create multiple users in a form submit fails, but creating a single new user works as designed. It appears the issue may be when saving the new user and then bringing the new user_id back in the return statement. Although the new id comes back, subsequent users (2nd, 3rd, etc) all get the same id value, and it appears that the subsequent $this->save calls modify the first created user rather than create add'l ones. Any none of the new users appear in the database. (again, the problem only happens when more than one new users will be created.)
My one small clue is that if I var_dump($user) in my importPublicLDAPUser() function (user.php) just after the $user = $this->save(array('User' => array( ... ))); then for the first element I see both 'modified' and 'created', whereas I see only 'modified' for the rest. This leads me to believe there's a step missing, like the user needs to be saved or commit (??) before the next user can be be created.
I tried changing this to $user = $this->User->save(array('group_id' => 3, ... and adding a 'create' before: $this->User->create(); but these produce errors 'Call to a member function save() on a non-object' and 'Call to a member function create() on a non-object'.
My application manages documents. Each document can have many authors, so it has controllers for: docs, doc-types, users, groups, and authors.
When a new document is entered, the form allows selection of multiple users to create 'Author' records. In addition to the local users table, it also searches our LDAP server (both via auto-sugggest) and also allows input into a text field. So, Authors are selected from
the existing table of users
via the LDAP helper
free text entry.
This result is two arrays: $Authors (from local users tables), and $badAuthors (LDAP and text-input) which the app then tries to add to the local users table when the form is submitted.
The form works just fine if:
one or more authors are added from local users table;
a single author is added from LDAP (succeeds in creating a new entry in users table), and zero or more local users
a single author is added from text input (also succeeds), and zero or more local users
However if two or more non-local users are added ($badAuthors has more than one element) then the form fails. "fails" means that either the Author or User save routine failed, and so it skips the Document commit $this->Docu->commit(); and I spit out an error via ajaxResponse. Thus, the app works as designed, but only with one new User entry at a time, even though the form is designed to allow Authors/badAuthors to be >1.
What I don't understand is why when I loop through bad authors why it doesn't correctly add the users if $badAuthors has more than one element.
As the user enters each name (which is checked against the users table and LDAP via ajax helpers, etc) and then selected, an author_name_list array is built. And then:
foreach($this->params['form']['author_name_list'] as $author_name){
$user_id = $this->Docu->User->field('id',array('User.name' => $author_name));
if($user_id){
$Authors['Author'][]=array(
'docu_id'=>$this->Docu->id
,'user_id'=>$user_id
);
}else{
$badAuthors[] = array('name'=>$author_name);
}
}
So $badAuthors is now those found in LDAP or entered manually.
So now I try to create/save all badAuthors...
docu controller (docu_controller.php):
if(count($badAuthors)){
foreach($badAuthors as $key => $author){
$this->Memo->User->create(); // ** <-- this was missing!! **
if($ldap_author = $this->Docu->User->importPublicLDAPUser($author['name'])){
unset($badAuthors[$key]);
$Authors['Author'] []= array(
'docu_id'=>$this->Docu->id
,'user_id'=>$ldap_author['User']['id']
,'precedence' => $author['precedence']
);
} elseif ($new_author = $this->Docu->User->newReadonlyUser($author['name'])) {
unset($badAuthors[$key]);
$Authors['Author'] []= array(
'docu_id'=>$this->Docu->id
,'user_id'=>$new_author['User']['id']
,'precedence' => $author['precedence']
);
}
}
}
if(!count($badAuthors)){
$authors_saved = true;
foreach($Authors['Author'] as $author_arr){
$this->Docu->Author->create();
if(!$this->Docu->Author->save(array('Author' => $author_arr))){
$authors_saved = false;
break;
}
}
}
user model (user.php)
function afterSave($created) {
if (!$created) {
$parent = $this->parentNode();
$parent = $this->node($parent);
$node = $this->node();
$aro = $node[0];
$aro['Aro']['parent_id'] = $parent[0]['Aro']['id'];
$this->Aro->save($aro);
}
}
function importPublicLDAPUser($cn){
App::import('Vendor','adLDAP',array('file'=>'adLDAP.php'));
$oLDAP = new adLDAP(Configure::read('LDAP_options.email'));
$oLDAP->authenticate(NULL, NULL);
$filter = '(&(cn='.$oLDAP->ldap_escape($cn).'))';
$ldap_res = #$oLDAP->search($filter, array('cn', 'uid','profitcenter'),1);
if(isset($ldap_res['count']) && ($ldap_res['count'] > 0)){//found it
$user = $this->save(array('User' => array(
'group_id' => 3,
'name' => $ldap_res[0]['cn'][0],
'username' => $ldap_res[0]['uid'][0],
'grpnum' => pc2grpnum($ldap_res[0]['profitcenter'][0])
)));
if($user){
$user['User']['id'] = $this->id;
}
return ($user ? $user : false);
}else{
return false;
}
}
Any suggestions? Thanks!!
It turns out that in my docu_controller.php I was missing a create() call. It seems that without a create, an object can still be saved/created when the other controller does a commit(). So before adding the create(), prior to the commit, in later loop iterations I was still modifying the original object, not any new ones. By adding a create in the controller, the save in the method function acts on the new user for each loop iteration.
in controller:
if(count($badAuthors)){
foreach($badAuthors as $key => $author){
$this->Memo->User->create();
if($ldap_author = $this->Memo->User->importPublicLDAPUser($author['name'])){
in method:
function importPublicLDAPUser($cn){
....
$user = $this->save(array('User' => array(...

Saving multiple records for multiple models cakephp

Hey guys, I'm super stuck after a long night.
I'm creating an app where you can create food menus dynamically, and have relationships set up as such: Menu hasMany Widget, Widget hasMany WidgetItem (and of course, WidgetItem belongsTo Widget, Widget belongsTo Menu).
The menu is created first, then the user is redirected to addSectionsToMenu, where I have set up multiple Widgets (title input), respectively with multiple items (menu items).
My widgets save and attach to the menu fine, but my WidgetItems don't save. My models are set up fine I am sure, and I spent 2 hours sorting out my $data structure. I just think I need to figure something out here.
Please help!
Thanks,
~Harley
function addSectionsToMenu($menu_id = null){
$this->layout = 'admin';
$this->set('menu_id', $menu_id);
$this->set('menu', $this->Widget->Menu->findById($menu_id));
if (!$menu_id && empty($this->data)) { $this->Session->setFlash(__('Pick a menu to add to please :)', true)); }
$saveSuccess = false;
if(!empty($this->data['Widget'])) {
$widget_count = 0;
foreach($this->data['Widget'] as $widgetKey => $widget) :
if($this->Widget->saveAll($widget)) : $saveSuccess = true; endif;
$widget_count++;
endforeach;
if ($saveSuccess) {
$this->Session->setFlash(__($widget_count.' sections have been added to the Menu', true));
$this->redirect(array('controller' => 'menus', 'action' => 'index'));
} else {
$this->Session->setFlash(__('The Menu and Sections could not be saved. Please, try again.', true));
}
}
}
I've had problems saving multiple models at once and I solved it by adjusting the validation option.
$this->Invoice->saveAll($this->data, array('validate' => true))
The explanation of the options array doesn't make complete sense to me, but the default was causing my insert to fail because the related records were not getting their foreign key from the insert of the parent record. Changing the option to "first" (the default) to "true" solved the problem and the rows are showing up in the database correctly.

Resources