Looking at the CiviCRM forums I saw that there was a real need for members only pricing for events in general, and the ability to manipulate price sets overall. I also have a customer who has made this a requirement in their proposal, and I wanted to take a stab at adding functionality to CiviCRM. The buildAmount hook works fine for regular pricing, but doesn't allow us to modify price sets.
Thanks to this post from Torrenware, and plenty of help from Donald Lobo on IRC, I have been able to put together a buildPriceOptions hook and a module that handles members only pricing.
In the attached file, you will find 2 patch files and a folder with the module. The patches are applied to two core files CRM/Utils/Hook.php and CRM/Price/BAO/Field.php, and just adds support for the hook. I know that it is against all twelve commandments to modify core, but it was necessary for this project.
What made this project challenging is that it was not readily apparent how it should work. I originally created a buildPriceSet hook that modified the price set in CRM/Price/BAO/Set.php. I ran through XDebug for hours trying to figure out why it wouldn't work. What I finally discovered is that, although there is a beautiful price set array structure, it is never used to build the final form. The price field id numbers are grabbed from the price set structure, then CRM/Price/BAO/Field::getOptions is called to grab the options right from the database. Based on this discovery, I decided to go back to the drawing board and recreate the hook.
How Does It Work
When you create a price set option, there will be a new select menu added to the form. This menu contains the groups in the system. You can select one or more groups to allow access to this price option, or select everyone to allow public access. When the registration form is generated, a custom table is queried to get the list of groups allowed to access each option, and if the current user does not have access that option is deleted.
I haven't written the module installer yet, so you will have to create a new table in your CiviCRM database using the following SQL
-- -- Table structure for table `civicrm_memberprice` -- CREATE TABLE IF NOT EXISTS `civicrm_memberprice` ( `gid` int(11) NOT NULL COMMENT 'group id allowed to use this price', `oid` int(11) NOT NULL COMMENT 'option field id' ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
This module has been lightly tested and is definitely beta quality software. Two of my clients are using this in production, and I will be release updates as issues arise.
You can download the module from Github.