Accessing table in db

Hi,

I created a table in db through my plugin at install time using this command,

$db = get_db();
$db->query("CREATE TABLE IF NOT EXISTS {$db->prefix}groups (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
user_id int(10) unsigned NOT NULL,

Question:
if I would like to retrieve data from the table, What command I need to use?
I tried to use select this way but it result empty object.

$db = get_db();
$result = $db->query("Select id,name from {$db->prefix}groups");

Do I need to create a class of Omeka_Db_Table to use built in functionality or there is another way, and if I do need to is there a documentation or a code I can look at it to figure out what functions I need to add to the class after I created?

my goal to create a group table, then perform sql commands like select, update insert..

thanks
Nancy

Generally, the way to do that is by first creating your table on install as you are doing. Then you would create a class model that extends Omeka_Record. That gives you all the methods to create, save, update, etc.

For more complex SQL work, you can create a related table class that extends Omeka_Db_Table, but that is often not necessary, as Omeka_Db_Table provides a lot of functionality with extending it.

You could probably look at the SimplePages plugin, in the models directory, to get a sense of how it works.

Thanks, I did create a class of Omeka_Record. It works fine now.
Thanks
Nancy

Hi Patrick,

in my plugin I create a table like that:
$db->query("CREATE TABLE IF NOT EXISTS {$db->prefix}groupping (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
entity_id int(10) unsigned NOT NULL,
group_id int(10) unsigned NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;");

Then I create a class of Omeka_Record, called
inside this class I have updateGroupping function that will be called from my controller when I call edit action. it sends the user object. the purpose of this function is update the grouping table with entity_id and group_id. it save the information fine, but problem happen when I do have two rows to insert. e.g (entity_id,group_id) values ('63','44') and values ('63',45')

which means the user with id 63 has two values 44 and 45. it does not insert both it insert only one row.

I looked in many areas but I could not figure out why it behave like that. I am sending to queries but it perform only one.
public function updateGroupping($user)
{
foreach($user['group'] as $group){
$groupping = new Omlibrarygroupping();
$groupping->entity_id = $user['entity_id'];
$groupping->group_id = $group;

$groupping->save();
}

}

I'm guessing that the data in the $user['group'] array is not being set up correctly. Assuming that your class that extends Omeka_Record is called Omlibrarygrouping, a cleaner and easier to debug way might be to set things up differently.

Since your updateGroupping method is creating and saving brand new records, that should probably happen in your edit action. So, if you have the $user object and the array of $groups, in your edit action you would do something like:

foreach($groups as $group)
{
    $newGrouping = new Omlibrarygrouping;
    $newGrouping->entity_id = $user->entity_id;
    $newGrouping->group_id = $group;
    $newGrouping->save()
}

As long as that array $group has the ids in it, that should create the records, and keep things more in line with usual patters on Omeka.

HTH

Thanks Patrick,

but I tried even that early in the morning and I tried it again now but still it save the last data in the group. I attach the code I do have in edit action. Do you think maybe I can not add two records with same entity_id?

public function editAction() {

$user = $this->findById();
$changePasswordForm = new Omeka_Form_ChangePassword;
$changePasswordForm->setUser($user);

$currentUser = $this->getCurrentUser();
// Super users don't need to know the current password.
if ($currentUser && $currentUser->role == 'super') {
// $changePasswordForm->removeElement('current_password');
}

//$this->view->passwordForm = $changePasswordForm;
$this->view->user = $user;

try {

if ($user->saveForm($_POST)) {

// $this->flashSuccess('The user "' . $user->username . '" was successfully changed!');
//delete all groups related to user with this entity_id
$groupping = new Omlibrarygroupping;
$groupping->deleteGroupingRecords($user['entity_id']);
// add groups selected for this user
$groups = $user['groups'];
foreach($groups as $group)
{
$newGrouping = new Omlibrarygroupping;
$newGrouping->entity_id = $user->entity_id;
$newGrouping->group_id = $group;
$newGrouping->save();
}

//$groupping->updateGroupping($user);// exit;
//exit;

if ($user->id == $currentUser->id) {
$this->_helper->redirector->gotoUrl('/');
} else {
$this->_helper->redirector->gotoUrl('/users/browse');
}
}
} catch (Omeka_Validator_Exception $e) {
$this->flashValidationErrors($e);

} catch (Exception $e) {
$this->flashError($e->getMessage());

}
// print_r('test');
//exit;
}

thanks

Patrick, it works, I found out I made the entity_id and group_id unique keys to avoid duplicate rows. that avoid the second row from inserted. when I take it out it work perfect.
thanks a lot.
Nancy

Glad it worked!

My controller extends from Userscontroller like that:

class Omlibrary_OmlibraryController extends UsersController {

I tried to Add delete Action function, like that.

public function deleteAction() {

}

but still it is not called when I click on delete button next to any user in user browse page.

Is there any further step I need to do. I even tried to add it to the router like that

$route = new Zend_Controller_Router_Route(
'users/delete/',
array(
'module' => 'omlibrary',
'controller' => 'omlibrary',
'action' => 'delete'
));

$router->addRoute('deleteOmlibraryUser', $route);

but it did not call my deleteAction.

I notice in Userscontroller.php they do not have deleteAction but I guess it run deleteAction in Omeka_Controller_Action. But since I extends Userscontroller and Userscontroller extends Omeka_Controller_Action still my deleteAction should be fine.

Do I need to add it to router.ini?

Depending on the details of the rest of the functionality, I see two directions that might simplify things. If all you need to do is some additional actions when a user is deleted, then it will be easier to use the various built-in hooks. The before_delete_user hook will let you perform additional actions when the user is deleted.

On the other hand, if what you are aiming for is managing groupings of users, it might work better to create your own admin tab for doing that and extending Omeka_Controller_Action directly, since the records you are really working with are Omlibarygroupings, not Users.

Thanks patrick,

I will need to use the before_delete_user because I am trying to clear up the grouping relation ship table when I delete any user. So the relation ship table has the user id and groupid, so every time I delete a user, I do need to before the delete to the grouping table too.

But in the future when I will build a plug in for group, I will do you second suggestion.

Mean while, I was trying to create a controller and extend it from exhibitscontroller. The reason behind this is, when the user click on edit or add in exhibit-metadata-form I will perform different actions.

I tried to use after save hook, but I was not sure how to know if the user clicked on Add or edit. I checked $post, $exhibit, $user but I did not see the value of the action that performed. So I though to create a second controller for exhibits in addition to my first controller that works ok that extends from users.

I do not think my controller has a problem but maybe the router. I am attaching the code of the router in case I am doing something wrong.

class OmexhibitControllerPlugin extends Zend_Controller_Plugin_Abstract {

public function routeStartup(Zend_Controller_Request_Abstract $request) {
$router = Omeka_Context::getInstance()->getFrontController()->getRouter();

$route = new Zend_Controller_Router_Route(
'exhibits/add',
array(
'module' => 'omlibrary',
'controller' => 'Omexhibit',
'action' => 'add'
));

$router->addRoute('addOmexhibit', $route);
}
}

class OmlibraryControllerPlugin extends Zend_Controller_Plugin_Abstract {

public function routeStartup(Zend_Controller_Request_Abstract $request) {
$router = Omeka_Context::getInstance()->getFrontController()->getRouter();

$route = new Zend_Controller_Router_Route(
'users/add/',
array(
'module' => 'omlibrary',
'controller' => 'omlibrary',
'action' => 'add'
));

$router->addRoute('addOmlibraryUser', $route);

$route = new Zend_Controller_Router_Route(
'users/edit/:id',
array(
'module' => 'omlibrary',
'controller' => 'omlibrary',
'action' => 'edit'
));

$router->addRoute('editOmlibraryUser', $route);
}

}

thanks
Nancy

You don't need to extend Zend_Controller_Plugin_Abstract. Your plugin's plugin.php file runs all the hooks and filters you define without needing to get near the level of the Zend classes.

That includes the define_routes hook, but you will probably not want or need to try that. That's because the same pattern of hooks I described above like before_delete_user works for all record types. So, if you need to do things after an exhibit is saved, you can do that with the before_save_exhibit hook. Those hooks are really one of the most powerful features of Omeka, and will likely let you do all that you need without resorting to subclasses and routes.

Thanks Patrick,

I am almost there and wrapping up the project to release soon. I build the group thing and link it to users and exhibits. Now each user can be part of one to > group and each exhibit can be link to 1 group for now. Users will be able to edit and delete exhibits that is linked to the user's group.

The next step is creating a group plugin to admin group e.g edit, delete, browse...

but I do have a question for group plugin.
As you said I do need "On the other hand, if what you are aiming for is managing groupings of users, it might work better to create your own admin tab for doing that and extending Omeka_Controller_Action directly, since the records you are really working with are Omlibarygroupings, not Users."

if I will build such controller do I need to implement a router and extend it from Zend_Controller_Plugin_Abstract in my plugin. in your previous post you said No, then how would my controller will receive edit, add, delete actions?
thanks
Nancy

The documentation about MVC and URL Paths is incomplete, but I think the info about URL paths is complete enough to get what you need. In a nutshell, there are default routes that match up controllers, actions, and view pages. So, a controller called Omlibrary_IndexController in the file controllers/IndexController.php in your plugin, and a view page at /views/admin/index/show.php will automatically connect without you defining any new routes.

The same pattern will work even for methods that do not already exist on Omeka_Controller_Action. So, for example, if you create a new method, awesomeAction() in your controller, a view at admin/index/awesome.php can display the data that the controller passes into it.

For most cases, though, the existing add, edit, delete, and browse actions will cover what's needed without adding anything more.

Thanks Patrick,

But what would you do for logout action where I do not have a view?

I have logoutAction defined in my controller and I removed this part from my plugin, but the lougout action would not be called.

class CosignControllerPlugin extends Zend_Controller_Plugin_Abstract {

public function routeStartup(Zend_Controller_Request_Abstract $request) {
$router = Omeka_Context::getInstance()->getFrontController()->getRouter();

$route = new Zend_Controller_Router_Route(
'users/logout',
array(
'module' => 'cosign',
'controller' => 'cosign',
'action' => 'logout'
));

$router->addRoute('logoutCosignUser', $route);

}

}

Also,

I see under application folder e.g for user controllers there is usercontrollers under controllers, and views corresponding to actions under views but I saw also forms folder which has the user form and login form ... which is a class extend from omeka form. Do I need that too? if not how would I refer to form object in my actions? I do not see that mentioned in the MVC and URL path documentation.

I might be getting a little confused -- I had understood the direction of this thread to be working with groupings of users. In that case, it seemed to me like the easiest course of action would be the approach of creating a model for the groupings and managing them either with hooks or by building a new manage view for the admin side.

This seems like it is moving in a different direction to a different plugin. If that's correct, just to help keep threads consistent it will help to make this a new post. Is this moving back to your post about Cosign? If so, I apologize that we haven't responded to it.

From what I see here, you shouldn't need to extend Zend_Controller_Plugin_Abstract. Omeka's define_routes hook should do the trick. The argument passed to the callback for the hook is the $router, so much of what's here can be simplified that way. I don't know, however, if that is the actual source of the problem.

Regarding your question about forms, each controller and view will access them and display them as needed. The place to look to see how that happens is in the UserController. I'm pretty sure all the forms files have been loaded, so you can just do new Omeka_Form_User as needed. The _getUserForm method in UserController will show how it works.

Sorry Patrick,
I jumped to new topick fast. yes my question should be moved to the cosign post. I will follow up there!
Thanks
Nancy