Developing a new module - not getting far

cowmoo

Joined: 2007-07-18
Posts: 20
Posted: Wed, 2007-07-18 05:31

Hey all,
Just started working with G2, and have been looking into creating a module.
I want the module to add some permissions (everyone group - core.viewAll) to an image/album, by clicking a link (in the sidebar or under image). Is there a module like this that anyone knows of?

I currently am using useralbum (with edited default permissions) to set permissions so only the user who created/uploaded an album/image can see them.
However I need the option to allow certain images/albums to be viewed by everyone, chosen by the user, so it needs to be in a link.

I've been working with a few modules (tutorial module, jensperms, ItemPermissions.inc) but am not getting very far.
I'm having trouble getting the image/album id to be passed into the module, I just can't seem to get it.
Every time I run the module I get the following error:

Error (ERROR_PERMISSION_DENIED) : user id: 6 doesn't have permission: core.addDataItem for item id:

* in modules/core/classes/helpers/GalleryUserHelper_simple.class at line 47 (GalleryCoreApi::error)
* in modules/core/classes/GalleryCoreApi.class at line 477 (GalleryUserHelper_simple::assertHasItemPermission)
* in modules/publiclink/MyPage.inc at line 51 (GalleryCoreApi::assertHasItemPermission)
* in main.php at line 231 (MyPageController::handleRequest)
* in main.php at line 94
* in main.php at line 83

From what I can see it doesn't seem to be passing the itemId correctly.
I'm trying to access itemId with

GalleryUtilities::getRequestVariables('itemId');

I'm simply running the module by typing the url http://www.example.com/main.php?g2_view=publiclink.MyPage
I'm logged in as admin.

Unfortunately I can't give the URL for the gallery2 install, heres the sys info.

Gallery version 2.2.2
PHP version 5.2.1 apache2handler
Webserver Apache/2.2.3 (Ubuntu) DAV/2 SVN/1.4.3 PHP/5.2.1
Database mysqli 5.0.38-Ubuntu_0ubuntu1-log
Toolkits ImageMagick, Thumbnail, Gd
Operating system Linux <boxname> 2.6.20-16-generic #2 SMP Thu Jun 7 20:19:32 UTC 2007 i686
Browser Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.4) Gecko/20061201 Firefox/2.0.0.4 (Ubuntu-feisty)

I've searched for adays through the forum and can't find anything (easy enough for me to understand).
I can give more info if needed.

Any help would be greatly appreciated.

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Wed, 2007-07-18 07:06

> I'm simply running the module by typing the url http://www.example.com/main.php?g2_view=publiclink.MyPage

you want the itemId to be part of the request but obviously there's no itemId parameter in that URL.

> However I need the option to allow certain images/albums to be viewed by everyone, chosen by the user, so it needs to be in a link.

so you don't want to give the owner the "change permission" permission, right? else they could change this on their own with the "edit permissions" link.

you'll want to use GalleryCoreApi::addGroupPermission(....) and GalleryCoreApi::removeGroupPermission(....)for this.

--------------
Documentation: Support / Troubleshooting | Installation, Upgrade, Configuration and Usage

 
cowmoo

Joined: 2007-07-18
Posts: 20
Posted: Wed, 2007-07-18 07:56

Thanks for the reply, I should've been more precise with my post.

When accessing the url I have tried http://www.example.com/main.php?g2_view=publiclink.MyPage?itemId=xxx, doesn't seem to get me any further, just loads the same page (modules/publiclink/templates/MyPage.tpl).

That's right, I don't want to give the users the ability to change any permissions, just to add/remove the specific permissions I want.

I'm trying to use

$ret = GalleryCoreApi::addGroupPermission($itemId, $core['id.everybodyGroup'], 'core.viewAll', FALSE);

to set permissions, but I just can't seem to get in the itemId.

I have found this post (2nd post on page): http://gallery.menalto.com/node/63690
which seems to be useful, unfortunately I don't have the time to go through it now, but will work further on this tomorrow.

Again, thanks for the reply, must be frustrating dealing with all the questions on this board. :p

I'll update this thread with any more info (success or failure) that I come across.

Just for reference, heres my handleRequest function (in /modules/publiclink/MyPage.inc) (half destroyed from the tutorial module):

    function handleRequest($form) {
        $status = $error = array();
		
		if (isset($form['action']['SetPublic'])) {
            if (strlen($form['SetPub']) != 3) {
                $error[] = 'form[error][SetPub]';
            } else {
		$itemId = GalleryUtilities::getRequestVariables('form[itemId]');
		list ($ret, $albumId) = GalleryUtilities::getRequestVariables('form[SetPub]');

		list ($ret, $aldumId) = $itemId;
                if ($ret) {
                    return array($ret, null);
                }
                if ($ret) {
                    return array($ret, null);
                }
                list ($ret, $lockId) = GalleryCoreApi::acquireWriteLock($albumId);
                if ($ret) {
                    return array($ret, null);
                }
                list ($ret, $album) = GalleryCoreApi::loadEntitiesById($albumId);
                if ($ret) {
                    GalleryCoreApi::releaseLocks($lockId);
                    return array($ret, null);
                }
		/* $ret = GalleryCoreApi::addGroupPermission($itemId, $group->getId(),$permission, $applyToChildren); */
		$ret = GalleryCoreApi::addGroupPermission($itemId, $core['id.everybodyGroup'], 'core.viewAll', FALSE);
                $ret = $album->save();
                if ($ret) {
                    GalleryCoreApi::releaseLocks($lockId);
                    return array($ret, null);
                }
                $ret = GalleryCoreApi::releaseLocks($lockId);
                if ($ret) {
                    return array($ret, null);
                }
                $status['saved'] = 1;
            }
        }
        $method = empty($error) ? 'redirect' : 'delegate';
        $result = array($method => array('view' => 'publiclink.MyPage'),
                        'status' => $status, 'error' => $error);
        return array(null, $result);
    }

I know it's all over the place atm (and not following coding standards), just put it here for reference, will fix up when I get working.

 
valiant

Joined: 2003-01-04
Posts: 32509
Posted: Wed, 2007-07-18 09:39

> When accessing the url I have tried http://www.example.com/main.php?g2_view=publiclink.MyPage?itemId=xxx, doesn't seem to get me any further, just loads the same page (modules/publiclink/templates/MyPage.tpl).

should be g2_itemId= and not itemId=

--------------
Documentation: Support / Troubleshooting | Installation, Upgrade, Configuration and Usage

 
cowmoo

Joined: 2007-07-18
Posts: 20
Posted: Thu, 2007-07-19 04:07

Thanks for the response again, valiant.

I've now got things working quite well, just need to make it work from account without changePermission permission (best way to do this??).

Currently calling it with:

http://www.example.com/main.php?g2_view=core.ItemAdmin&g2_subView=publiclink.SetPerms&g2_itemId=xxx

This page simply shows a message displaying the current status (public/private), a button with "Make Public" or "Make Private", click the button it toggles whether the Everybody - core.viewAll is present or not (child items also inherit this).

Which seems to work fine.

I started again from the ground up and basically ended up with a simplified copy of ItemPermissions (view and controller).

Also need to create a block to display the link where I want it, but that shouldn't be that hard now that I'm getting an understanding of the structure of G2, I'll post back once I've done it.

Does all that sound right? :p

I'll also post the code soon, after it's been cleaned up.

Oh and Aosh, thanks for that post, helped quite a bit.

cOwMoO

 
cowmoo

Joined: 2007-07-18
Posts: 20
Posted: Wed, 2007-10-10 07:07

Well it's been a while since I was here (other work got the better of me) but I've started developing this module again, got it working quite nicely, although not exactly how I originally wanted it.
Basically I have 2 questions, the first being, is there any way I can perform actions in a block without ever going to a view? I want the user to be able to click a button/link in the block, and have it set certain permissions (in this case 'Everybody.viewAll'), and take the user straight back to the page they were viewing.
Right now they must click a link, which takes them to a view, from there they click a button which sets the permissions and takes them back to the original page they were viewing.

My other question is, can anyone see any improvements I can make to the following code, I'm sure there will be some, as I'm still not too familiar with the G2 framework and this is just a hacked up version of ItemPermissions.inc so I'm not 100% sure of what all the lines do.

Anyway, thanks in advance for any help, and also to the Dev team, fantastic product!


class SetPermsController extends GalleryController {

    /**
     * @see GalleryController::handleRequest
     */
    function handleRequest($form) {

	global $gallery;
	$itemId = GalleryUtilities::getRequestVariables('itemId');
	$applyToChildren = isset($form['applyToSubItems']);

	/* Make sure we have permission to change permissions of this item */
	//$ret = GalleryCoreApi::assertHasItemPermission($itemId, 'core.changePermissions');
	/*if ($ret) {
		$ret = GalleryCoreApi::addUserPermission($itemId, $gallery->getActiveUserId(),
		'core.changePermissions', $applyToChildren);
	    return array($ret, null);
	}*/

	$status = $error = array();

	if (isset($form['action']['deleteGroupPermission'])) {
	    /* Figure out which one we're working with */
	    $deleteGroupPermission = array_keys($form['action']['deleteGroupPermission']);
	    $index = array_pop($deleteGroupPermission);

	    /* Handle delete group perm actions */
	    list ($groupId, $permissionId) = explode(',', $form['group']['delete'][$index]);
	    $ret = GalleryCoreApi::removeGroupPermission($itemId, $groupId,
		$permissionId, $applyToChildren);
	    if ($ret) {
		return array($ret, null);
	    }

	    /* Figure out where to redirect upon success */
	    $redirect['view'] = '';
	    $redirect['subView'] = '';
	    $redirect['itemId'] = $itemId;
	    $status['deletedGroupPermission'] = 1;
	    $verifySelfPermissions = true;

	} else if (isset($form['action']['addGroupPermission'])) {

	    /* Handle add group permission actions */
	    if (empty($form['group']['groupName'])) {
			$error[] = 'form[error][group][missingGroup]';
	    } else {
			/* Validate the group */
			list ($ret, $group) =
		    GalleryCoreApi::fetchGroupByGroupName($form['group']['groupName']);
			if ($ret) {
		    	if ($ret->getErrorCode() & ERROR_MISSING_OBJECT) {
					$error[] = 'form[error][group][invalidGroup]';
		    	} else {
					return array($ret, null);
		   		}
			}
	    }

	    /* Validate the permission */
	    $permission = $form['group']['permission'];
	    list ($ret, $allPermissions) = GalleryCoreApi::getPermissionIds();
	    if ($ret) {
		return array($ret, null);
	    }
	    if (empty($allPermissions[$permission])) {
		$error[] = 'form[error][group][invalidPermission]';
	    }

	    if (empty($error)) {
		/* Don't add the permission if it already exists */
		list ($ret, $hasIt) =
		    GalleryCoreApi::hasPermission($itemId, $group->getId(), $permission);
		if ($ret) {
		    return array($ret, null);
		}
		if ($hasIt) {
		    $error[] = 'form[error][group][alreadyHadPermission]';
		}
	    }

	    if (empty($error)) {
		$ret = GalleryCoreApi::addGroupPermission($itemId, $group->getId(),
							  $permission, $applyToChildren);
		if ($ret) {
		    return array($ret, null);
		}

		/* Figure out where to redirect upon success */
		$redirect['view'] = '';
		$redirect['subView'] = '';
		$redirect['itemId'] = $itemId;
		$redirect['form[group][groupName]'] = $group->getGroupName();
		$status['addedGroupPermission'] = 1;
	    }
	}

	if (isset($verifySelfPermissions)) {
	    /*
	     * Make sure we don't remove our own ability to change permissions on this item.
	     * If this was a recursive remove we may lose permissions on subitems.
	     */
	    list ($ret, $canEdit) = GalleryCoreApi::hasItemPermission($itemId, 'core.edit');
	    if ($ret) {
		return array($ret, null);
	    }
	    /* if (!$canEdit) {
		$ret = GalleryCoreApi::addUserPermission($itemId, $gallery->getActiveUserId(),
							 'core.edit', $applyToChildren);
		if ($ret) {
		    return array($ret, null);
		}
		$status['addedBackSelfPermission'] = 1;
	    }*/
	    list ($ret, $canChange) =
		GalleryCoreApi::hasItemPermission($itemId, 'core.changePermissions');
	    if ($ret) {
		return array($ret, null);
	    }
	    if (!$canChange) {
		$ret = GalleryCoreApi::addUserPermission($itemId, $gallery->getActiveUserId(),
							 'core.changePermissions', $applyToChildren);
		if ($ret) {
		    return array($ret, null);
		}
		$status['addedBackSelfPermission'] = 1;
	    }
	}

	if (empty($error)) {
	    /*
	     * Try compacting.  Ignore lock timeouts here; if we failed this time we'll try
	     * again next time.
	     */
	    $ret = GalleryCoreApi::maybeCompactAccessLists();
	    if ($ret && !($ret->getErrorCode() & ERROR_LOCK_TIMEOUT)) {
		return array($ret, null);
	    }
	}

	if (!empty($redirect)) {
	    $results['redirect'] = $redirect;
	} else {
	    $results['delegate']['view'] = 'core.ItemAdmin';
	    $results['delegate']['subView'] = 'publiclink.SetPerms';
	}
	$results['status'] = $status;
	$results['error'] = $error;

	return array(null, $results);
    }
}

/**
 * This view will prompt for permission settings of an item
 */
class SetPermsView extends GalleryView {

    /**
     * @see GalleryView::loadTemplate
     */
    function loadTemplate(&$template, &$form) {
	global $gallery;
	$itemId = GalleryUtilities::getRequestVariables('itemId');

	/* Make sure we have permission to edit this item */
	/*$ret = GalleryCoreApi::assertHasItemPermission($itemId, 'core.edit');
	if ($ret) {
		$ret = GalleryCoreApi::addUserPermission($itemId, $gallery->getActiveUserId(),
		'core.edit', $applyToChildren);
		$SetPerms = 1;
	    return array($ret, null);
	} */
	list ($ret, $canChange) =
	    GalleryCoreApi::hasItemPermission($itemId, 'core.changePermissions');
	if ($ret) {
	    return array($ret, null);
	}

	list ($ret, $item) = GalleryCoreApi::loadEntitiesById($itemId);
	if ($ret) {
	    return array($ret, null);
	}
	$form['serialNumber'] = $item->getSerialNumber();

	if ($form['formName'] == 'SetPerms') {
	    /* Complain if we have any invalid data */
	} else {
	    /*
	     * First time around, load the form with item data.  Note that
	     * userName and groupName can be passed in to this form so don't
	     * initialize them unless they don't exist.
	     */
	    if (empty($form['user']['userName'])) {
		$form['user']['userName'] = '';
	    }

	    if (empty($form['user']['permission'])) {
		$form['user']['permission'] = '';
	    }

	    if (empty($form['group']['groupName'])) {
		$form['group']['groupName'] = '';
	    }

	    if (empty($form['group']['permission'])) {
		$form['group']['permission'] = '';
	    }

	    $form['owner']['ownerName'] = '';
	    $form['formName'] = 'SetPerms';
	}

	/* Get all available permissions */
	list ($ret, $allPermissions) = GalleryCoreApi::getPermissionIds();
	if ($ret) {
	    return array($ret, null);
	}
	ksort($allPermissions);

	/* Get all permissions for the item. */
	list ($ret, $permissions) =
	    GalleryCoreApi::fetchAllPermissionsForItem($itemId, true);
	if ($ret) {
	    return array($ret, null);
	}

	/* Figure out all the unique user/group ids and load those */
	$userAndGroupEntityIds = array();
	foreach ($permissions as $permission) {
	    if (!empty($permission['userId'])) {
		$userAndGroupEntityIds[$permission['userId']] = 1;
	    }
	    if (!empty($permission['groupId'])) {
		$userAndGroupEntityIds[$permission['groupId']] = 1;
	    }
	}

	list ($ret, $userAndGroupEntities) =
	    GalleryCoreApi::loadEntitiesById(array_keys($userAndGroupEntityIds));
	if ($ret) {
	    return array($ret, null);
	}

	/* Convert them into a hash map by entity id */
	foreach ($userAndGroupEntities as $entity) {
	    $userAndGroupEntityMap[$entity->getId()] = (array)$entity;
	}

	/* Figure out the admin group id */
	list ($ret, $adminGroupId) =
	    GalleryCoreApi::getPluginParameter('module', 'core', 'id.adminGroup');
	if ($ret) {
	    return array($ret, null);
	}

	/*
	 * Now create the separate user and group permission maps.
	 *
	 * Silently ignore any permissions that we come across that aren't part
	 * of the permission registry.  They may be permission associated with
	 * modules that are not currently active.
	 */
	$userPermissions = $groupPermissions = array();
	foreach ($permissions as $permission) {
	    $permissionId = $permission['permission'];
	    if (!empty($permission['userId']) && isset($allPermissions[$permissionId])) {
		list ($ret, $subPermissions) = GalleryCoreApi::getSubPermissions($permissionId);
		if ($ret) {
		    return array($ret, null);
		}

		$userPermissions[] = array(
		    'permission' => array('id' => $permissionId,
					  'description' => $allPermissions[$permissionId]),
		    'user' => $userAndGroupEntityMap[$permission['userId']],
		    'deleteList' => $subPermissions);
	    }

	    if (!empty($permission['groupId']) && isset($allPermissions[$permissionId])) {
		if ($permission['groupId'] != $adminGroupId) {
		    list ($ret, $subPermissions) = GalleryCoreApi::getSubPermissions($permissionId);
		    if ($ret) {
			return array($ret, null);
		    }
		} else {
		    $subPermissions = array();
		}

		$groupPermissions[] =
		    array('permission' => array('id' => $permissionId,
						'description' => $allPermissions[$permissionId]),
			  'group' => $userAndGroupEntityMap[$permission['groupId']],
			  'deleteList' => $subPermissions);
	    }
	}

	/* Figure out the owner */
	list ($ret, $owner) = GalleryCoreApi::loadEntitiesById($item->getOwnerId());
	if ($ret) {
	    return array($ret, null);
	}

	list ($ret, $isAdmin) = GalleryCoreApi::isUserInSiteAdminGroup();
	if ($ret) {
	    return array($ret, null);
	}

	/* Figure out what we can display on the form */
	$can['changePermissions'] = $canChange;
	$can['changeOwner'] = $isAdmin;
	$can['applyToSubItems'] = $item->getCanContainChildren();

	$ItemPermissions['owner'] = (array)$owner;
	$ItemPermissions['can'] = $can;
	$ItemPermissions['userPermissions'] = $userPermissions;
	$ItemPermissions['groupPermissions'] = $groupPermissions;
	$ItemPermissions['allPermissions'] = $allPermissions;

	$template->setVariable('SetPerms', $ItemPermissions);
	$template->setVariable('controller', 'publiclink.SetPerms');
	return array(null, array('body' => 'modules/publiclink/templates/SetPerms.tpl'));
    }

    /**
     * @see GalleryView::getViewDescription
     */
    function getViewDescription() {
	list ($ret, $core) = GalleryCoreApi::loadPlugin('module', 'core');
	if ($ret) {
	    return array($ret, null);
	}

	list ($ret, $item) = $this->getItem();
	if ($ret) {
	    return array($ret, null);
	}

	$itemTypeNames = $item->itemTypeName(true);

	return array(null, $core->translate(array('text' => 'edit %s permissions',
						  'arg1' => $itemTypeNames[1])));
    }
}