def fixPersonRoles(context, userId): # Remove all other Owners of this Person object. Note that the creator will have an implicit # owner role. The User Preferences Editor role allows us to allow the user defined by the Person # to manage their own password and user preferences, but prevent the creator of the Person object # from modifying those fields. for owner in context.users_with_local_role('Owner'): roles = list(context.get_local_roles_for_userid(owner)) roles.remove('Owner') if roles: context.manage_setLocalRoles(owner, roles) else: context.manage_delLocalRoles([owner]) # Grant 'Owner' and 'User Preferences Editor' to the user defined by this object: roles = list(context.get_local_roles_for_userid(userId)) roles.extend(['Owner', 'User Preferences Editor']) # eliminate duplicated roles roles = list(set(roles)) context.manage_setLocalRoles(userId, roles) # Grant 'Owner' only to any users listed as 'assistants': for assistant in context.getReferences(relationship="people_assistants"): pid = assistant.id user = userFolder.getUserById(pid) if user is None: raise KeyError, _(u"User %s cannot be found.") % pid roles = list(context.get_local_roles_for_userid(pid)) roles.append('Owner') context.manage_setLocalRoles(pid, roles)
def fixPersonRoles(context, userId): # Remove all other Owners of this Person object. Note that the creator will have an implicit # owner role. The User Preferences Editor role allows us to allow the user defined by the Person # to manage their own password and user preferences, but prevent the creator of the Person object # from modifying those fields. for owner in context.users_with_local_role('Owner'): roles = list(context.get_local_roles_for_userid(owner)) roles.remove('Owner') if roles: context.manage_setLocalRoles(owner, roles) else: context.manage_delLocalRoles([owner]) # Grant 'Owner' and 'User Preferences Editor' to the user defined by this object: roles = list(context.get_local_roles_for_userid(userId)) roles.extend(['Owner', u'Reviewer', 'User Preferences Editor']) # eliminate duplicated roles roles = list(set(roles)) context.manage_setLocalRoles(userId, roles) # Grant 'Owner' only to any users listed as 'assistants': for assistant in context.getReferences( relationship="people_assistants"): pid = assistant.id user = userFolder.getUserById(pid) if user is None: raise KeyError, _(u"User %s cannot be found.") % pid roles = list(context.get_local_roles_for_userid(pid)) roles.append('Owner') context.manage_setLocalRoles(pid, roles)
def validate_id(self, value): """Ensure the id is unique, also among groups globally.""" if value != self.getId(): parent = aq_parent(aq_inner(self)) if value in parent.objectIds(): return _(u"An object with id '%s' already exists in this folder") % value groups = getToolByName(self, 'portal_groups') if groups.getGroupById(value) is not None: return _(u"A group with id '%s' already exists in the portal") % value
def validate_id(self, value): """Ensure the id is unique, also among groups globally.""" if value != self.getId(): parent = aq_parent(aq_inner(self)) if value in parent.objectIds(): return _("An object with id '%s' already exists in this folder" ) % value groups = getToolByName(self, 'portal_groups') if groups.getGroupById(value) is not None: return _("A group with id '%s' already exists in the portal" ) % value
def post_validate(self, REQUEST, errors): form = REQUEST.form if 'password' in form or 'confirmPassword' in form: password = form.get('password', None) confirm = form.get('confirmPassword', None) annotations = IAnnotations(self) passwordDigest = annotations.get(config.PASSWORD_KEY, None) if not passwordDigest: if not password and not confirm: errors['password'] = _(u'An initial password must be set') return if password or confirm: if password != confirm: errors['password'] = errors['confirmPassword'] = _(u'Passwords do not match')
def validate_officePhone(self, value=None): """ Make sure the phone number fits the regex defined in the configuration. """ if value: fsd_tool = getToolByName(self, TOOLNAME) regexString = fsd_tool.getPhoneNumberRegex() if regexString and not re.match(regexString, value): return _(u"Please provide the phone number in the format %s") % fsd_tool.getPhoneNumberDescription()
def post_validate(self, REQUEST, errors): form = REQUEST.form if form.has_key('password') or form.has_key('confirmPassword'): password = form.get('password', None) confirm = form.get('confirmPassword', None) annotations = IAnnotations(self) passwordDigest = annotations.get(PASSWORD_KEY, None) if not passwordDigest: if not password and not confirm: errors['password'] = _(u'An initial password must be set') return if password or confirm: if password != confirm: errors['password'] = errors['confirmPassword'] = _(u'Passwords do not match')
def validate_officePhone(self, value=None): """ Make sure the phone number fits the regex defined in the configuration. """ if value: fsd_tool = getToolByName(self, config.TOOLNAME) regexString = fsd_tool.getPhoneNumberRegex() if regexString and not re.match(regexString, value): return _(u"Please provide the phone number in the format %s") % ( fsd_tool.getPhoneNumberDescription())
def validate_id(self, value): """ """ # Ensure the ID is unique in this folder: if value != self.getId(): parent = aq_parent(aq_inner(self)) if value in parent.objectIds(): return _(u"An object with ID '%s' already exists in this folder") % value # Make sure the ID fits the regex defined in the configuration: fsd_tool = getToolByName(self, TOOLNAME) regexString = fsd_tool.getIdRegex() if not re.match(regexString, value): return fsd_tool.getIdRegexErrorMessage()
def validate_id(self, value): """ """ # Ensure the ID is unique in this folder: if value != self.getId(): parent = aq_parent(aq_inner(self)) if value in parent.objectIds(): return _(u"An object with ID '%s' already exists in this folder") % value # Make sure the ID fits the regex defined in the configuration: fsd_tool = getToolByName(self, config.TOOLNAME) regexString = fsd_tool.getIdRegex() if not re.match(regexString, value): return fsd_tool.getIdRegexErrorMessage()
__author__ = """WebLion <*****@*****.**>""" __docformat__ = 'plaintext' from AccessControl import ClassSecurityInfo from Products.Archetypes.atapi import * from Products.FacultyStaffDirectory.config import * from Products.FacultyStaffDirectory.interfaces.departmentalmembership import IDepartmentalMembership from zope.interface import implements from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = Schema(( StringField( name='position', widget=StringWidget( label=_(u"FacultyStaffDirectory_label_position", default=u"Position"), i18n_domain='FacultyStaffDirectory', ) ), StringField( name='title', widget=StringWidget( label=_(u"FacultyStaffDirectory_label_title", default=u"Title"), i18n_domain='FacultyStaffDirectory', visible={'edit': 'invisible', 'view': 'invisible' }, ) ), BooleanField( name='primary_department', widget=BooleanWidget(
from AccessControl import ClassSecurityInfo from Products.Archetypes.atapi import * from Products.FacultyStaffDirectory.config import * from Products.FacultyStaffDirectory.interfaces.specialtyinformation import ISpecialtyInformation from zope.interface import implements from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = Schema(( TextField( name='researchTopic', allowable_content_types=('text/plain', 'text/structured', 'text/html',), widget=RichWidget( label=_(u"FacultyStaffDirectory_label_researchTopic", default=u"Research Topic"), i18n_domain='FacultyStaffDirectory', allow_file_upload=False, rows=5, ), default_output_type='text/x-html-safe' ), StringField( name='title', default="Research Topic", widget=StringWidget( visible={'edit': 'invisible', 'view': 'visible'}, label=_(u"FacultyStaffDirectory_label_title", default=u"Title"), i18n_domain='FacultyStaffDirectory', ),
from AccessControl import ClassSecurityInfo from Products.Archetypes.atapi import * from Products.ATContentTypes.content.base import ATCTContent from Products.ATContentTypes.content.schemata import ATContentTypeSchema, finalizeATCTSchema from Products.FacultyStaffDirectory.config import * from Products.FacultyStaffDirectory.interfaces.committeemembership import ICommitteeMembership from zope.interface import implements from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = ATContentTypeSchema.copy() + Schema(( StringField( name='position', widget=StringWidget( label=_("FacultyStaffDirectory_label_position", default="Position"), i18n_domain='FacultyStaffDirectory', ) ), StringField( name='title', default="Position", widget=StringWidget( visible={'edit':'invisible', 'view':'visible'}, label=_("FacultyStaffDirectory_label_title", default="Title"), i18n_domain='FacultyStaffDirectory', ), accessor="Title" ),
from Products.Relations.field import RelationField from Products.FacultyStaffDirectory.config import * from zope.interface import implements from Products.CMFCore.utils import getToolByName from Products.membrane.at.interfaces import IPropertiesProvider from Products.FacultyStaffDirectory.interfaces.committee import ICommittee from Acquisition import aq_inner, aq_parent from Products.FacultyStaffDirectory.permissions import ASSIGN_COMMITTIES_TO_PEOPLE from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = Schema(( RelationField( name='members', widget=ReferenceBrowserWidget( label=_(u"FacultyStaffDirectory_label_members", default=u"Members"), i18n_domain='FacultyStaffDirectory', allow_browse=0, allow_search=1, show_results_without_query=1, base_query="_search_people_in_this_fsd", startup_directory_method="_get_parent_fsd_path", ), write_permission = ASSIGN_COMMITTIES_TO_PEOPLE, allowed_types=('FSDPerson',), multiValued=True, relationship='CommitteeMembership' ), ), )
"""Constructor validator - a validator (or ValidatorChain) to run against each item in the sequence. For reasonable results, make sure your chain cites the bad input in its error message. Otherwise, the user won't know what the error message applies to. """ self.name = name self.title = kw.get('title', name) self.description = description self.validator = validator def __call__(self, values, *args, **kwargs): errors = [self.validator(v) for v in values] errors = [x for x in errors if x not in (True, 1)] # Filter out non-errors. if errors: return '\n\n'.join(errors) else: # Not sure why this needs to be True, but returning 1 (like # RegexValidator) throws an Unsubscriptable Object exception. [Ed: # It's because that's what the IValidator interface proclaims. The # stock validators are just nonconformant.] return True classImplements(SequenceValidator, IValidator) # Change some error messages to improve grammar validation.validatorFor('isURL').errmsg = _(u'is not a valid URL.'),
}, pattern_options={ 'baseCriteria': [{ 'i': 'portal_type', 'o': 'plone.app.querystring.operation.string.is', 'v': 'FSDPerson', }], 'basePath': '', "contextPath": None, 'selectableTypes': [ 'FSDPerson', ], 'placeholder': _(u'Begin typing a name'), }, ), write_permission=ASSIGN_SPECIALTIES_TO_PEOPLE, allowed_types=('FSDPerson', ), multiValued=True, relationship= 'SpecialtyInformation' # weird relationship name is ArchGenXML's fault ), atapi.ImageField( name='overviewImage', schemata='Overview', widget=atapi.ImageWidget( label=_( u"FacultyStaffDirectory_label_overview_image", default=u"Overview image (used for specialty overview view)"
from Products.CMFPlone.interfaces import IPloneSiteRoot from Products.FacultyStaffDirectory import FSDMessageFactory as _ try: from Products.Archetypes.Widget import TinyMCEWidget except ImportError: TinyMCEWidget = atapi.RichWidget schema = ATContentTypeSchema.copy() + atapi.Schema(( atapi.TextField( name='text', allowable_content_types=config.ALLOWABLE_CONTENT_TYPES, widget=TinyMCEWidget( label=_("FacultyStaffDirectory_label_text", default="Body Text"), i18n_domain='FacultyStaffDirectory', ), default_output_type="text/x-html-safe", searchable=True, validators=('isTidyHtmlWithCleanup',) ), ), ) # + on Schemas does only a shallow copy PersonGrouping_schema = atapi.OrderedBaseFolderSchema.copy() + schema.copy() class PersonGrouping(atapi.OrderedBaseFolder, ATCTContent):
from Products.Archetypes.atapi import * from archetypes.referencebrowserwidget.widget import ReferenceBrowserWidget from Products.CMFCore.permissions import View from Products.FacultyStaffDirectory.PersonGrouping import PersonGrouping from Products.Relations.field import RelationField from Products.FacultyStaffDirectory.config import * from Products.CMFCore.utils import getToolByName from Products.FacultyStaffDirectory.interfaces.department import IDepartment from zope.interface import implements from Products.FacultyStaffDirectory.permissions import ASSIGN_DEPARTMENTS_TO_PEOPLE from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = Schema( (RelationField(name='members', widget=ReferenceBrowserWidget( label=_("FacultyStaffDirectory_label_members", default="Members"), i18n_domain='FacultyStaffDirectory', allow_browse=0, allow_search=1, show_results_without_query=1, base_query="_search_people_in_this_fsd", startup_directory_method="_get_parent_fsd_path", ), write_permission=ASSIGN_DEPARTMENTS_TO_PEOPLE, allowed_types=('FSDPerson', ), multiValued=1, relationship='departments_members'), ), ) Department_schema = getattr(PersonGrouping, 'schema', Schema( ())).copy() + schema.copy()
from Products.Archetypes.atapi import * from Products.FacultyStaffDirectory.config import * from Products.CMFCore.permissions import View from Products.ATContentTypes.content.base import ATCTContent from Products.ATContentTypes.content.schemata import ATContentTypeSchema, finalizeATCTSchema from Products.FacultyStaffDirectory.interfaces.course import ICourse from zope.interface import implements from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = ATContentTypeSchema.copy() + Schema(( StringField( name='abbreviation', widget=StringWidget( size="5", label=_(u"FacultyStaffDirectory_label_abbreviation", default=u"Abbreviation"), i18n_domain='FacultyStaffDirectory', ), searchable=True ), StringField( name='number', widget=StringWidget( label=_(u"FacultyStaffDirectory_label_number", default=u"Number"), i18n_domain='FacultyStaffDirectory', ), searchable=True ), TextField(
from Products.FacultyStaffDirectory import FSDMessageFactory as _ try: from Products.Archetypes.Widget import TinyMCEWidget except ImportError: TinyMCEWidget = atapi.RichWidget schema = atapi.Schema(( atapi.TextField(name='researchTopic', allowable_content_types=( 'text/plain', 'text/structured', 'text/html', ), widget=TinyMCEWidget( label=_("FacultyStaffDirectory_label_researchTopic", default="Research Topic"), i18n_domain='FacultyStaffDirectory', allow_file_upload=False, rows=5, ), default_output_type='text/x-html-safe'), atapi.StringField(name='title', default="Research Topic", widget=atapi.StringWidget( visible={ 'edit': 'invisible', 'view': 'visible' }, label=_("FacultyStaffDirectory_label_title", default="Title"), i18n_domain='FacultyStaffDirectory',
from Products.membrane.at.interfaces import IPropertiesProvider from Products.membrane.utils import getFilteredValidRolesForPortal from Acquisition import aq_inner, aq_parent from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = ATContentTypeSchema.copy() + Schema(( LinesField('roles_', accessor='getRoles', mutator='setRoles', edit_accessor='getRawRoles', vocabulary='getRoleSet', default = ['Member'], multiValued=1, write_permission=ManageUsers, widget=MultiSelectionWidget( label=_(u"FacultyStaffDirectory_label_FacultyStaffDirectoryRoles", default=u"Roles"), description=_(u"FacultyStaffDirectory_description_FacultyStaffDirectoryRoles", default=u"The roles all people in this directory will be granted site-wide"), i18n_domain="FacultyStaffDirectory", ), ), IntegerField('personClassificationViewThumbnailWidth', accessor='getClassificationViewThumbnailWidth', mutator='setClassificationViewThumbnailWidth', schemata='Display', default=100, write_permission=ManageUsers, widget=IntegerWidget( label=_(u"FacultyStaffDirectory_label_personClassificationViewThumbnailWidth", default=u"Width for thumbnails in classification view"), description=_(u"FacultyStaffDirectory_description_personClassificationViewThumbnailWidth", default=u"Show all person thumbnails with a fixed width (in pixels) within the classification view"), i18n_domain="FacultyStaffDirectory", ),
from Products.ATContentTypes.content.base import ATCTContent from Products.ATContentTypes.content.schemata import ATContentTypeSchema, finalizeATCTSchema from Products.FacultyStaffDirectory.interfaces.course import ICourse from zope.interface import implements from Products.FacultyStaffDirectory import FSDMessageFactory as _ try: from Products.Archetypes.Widget import TinyMCEWidget except ImportError: TinyMCEWidget = atapi.RichWidget schema = ATContentTypeSchema.copy() + atapi.Schema(( atapi.StringField(name='abbreviation', widget=atapi.StringWidget( size="5", label=_("FacultyStaffDirectory_label_abbreviation", default="Abbreviation"), i18n_domain='FacultyStaffDirectory', ), searchable=True), atapi.StringField(name='number', widget=atapi.StringWidget( label=_("FacultyStaffDirectory_label_number", default="Number"), i18n_domain='FacultyStaffDirectory', ), searchable=True), atapi.TextField(name='description', allowable_content_types=config.ALLOWABLE_CONTENT_TYPES, widget=TinyMCEWidget( label=_("FacultyStaffDirectory_label_description", default="Description"),
def modifyPersonOwnership(event): """Let people own their own objects and modify their own user preferences. Stolen from Plone and CMF core, but made less picky about where users are found. (and from borg, thanks, optilude!) """ context = event.context # Only run this if FSDPerson is an active membrane type. fsd_tool = getToolByName(context, 'facultystaffdirectory_tool') if 'FSDPerson' in fsd_tool.getEnableMembraneTypes(): catalog = getToolByName(context, 'portal_catalog') userId = IMembraneUserObject(context).getUserId() userFolder = getToolByName(context, 'acl_users') user = None while userFolder is not None: user = userFolder.getUserById(userId) if user is not None: break container = aq_parent(aq_inner(userFolder)) parent = aq_parent(aq_inner(container)) userFolder = getattr(parent, 'acl_users', None) if user is None: raise KeyError, _(u"User %s cannot be found.") % userId context.changeOwnership(user, False) def fixPersonRoles(context, userId): # Remove all other Owners of this Person object. Note that the creator will have an implicit # owner role. The User Preferences Editor role allows us to allow the user defined by the Person # to manage their own password and user preferences, but prevent the creator of the Person object # from modifying those fields. for owner in context.users_with_local_role('Owner'): roles = list(context.get_local_roles_for_userid(owner)) roles.remove('Owner') if roles: context.manage_setLocalRoles(owner, roles) else: context.manage_delLocalRoles([owner]) # Grant 'Owner' and 'User Preferences Editor' to the user defined by this object: roles = list(context.get_local_roles_for_userid(userId)) roles.extend(['Owner', 'User Preferences Editor']) # eliminate duplicated roles roles = list(set(roles)) context.manage_setLocalRoles(userId, roles) # Grant 'Owner' only to any users listed as 'assistants': for assistant in context.getReferences(relationship="people_assistants"): pid = assistant.id user = userFolder.getUserById(pid) if user is None: raise KeyError, _(u"User %s cannot be found.") % pid roles = list(context.get_local_roles_for_userid(pid)) roles.append('Owner') context.manage_setLocalRoles(pid, roles) fixPersonRoles(context, user.getId()) catalog.reindexObject(context)
from Products.ATContentTypes.content.base import ATCTContent from Products.ATContentTypes.content.schemata import ATContentTypeSchema from Products.FacultyStaffDirectory.config import * from Products.FacultyStaffDirectory.interfaces.facultystaffdirectory import IFacultyStaffDirectory from Products.CMFCore.permissions import View, ModifyPortalContent from Products.CMFCore.utils import getToolByName from Products.CMFPlone.interfaces import IPloneSiteRoot from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = ATContentTypeSchema.copy() + Schema(( TextField( name='text', allowable_content_types=ALLOWABLE_CONTENT_TYPES, widget=RichWidget( label=_(u"FacultyStaffDirectory_label_text", default=u"Body Text"), i18n_domain='FacultyStaffDirectory', ), default_output_type="text/x-html-safe", searchable=True, validators=('isTidyHtmlWithCleanup',) ), ), ) PersonGrouping_schema = OrderedBaseFolderSchema.copy() + schema.copy() # + on Schemas does only a shallow copy class PersonGrouping(OrderedBaseFolder, ATCTContent): """""" security = ClassSecurityInfo()
__author__ = """WebLion <*****@*****.**>""" __docformat__ = 'plaintext' from AccessControl import ClassSecurityInfo from Products.Archetypes.atapi import * from Products.FacultyStaffDirectory.config import * from Products.FacultyStaffDirectory.interfaces.departmentalmembership import IDepartmentalMembership from zope.interface import implements from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = Schema(( StringField( name='position', widget=StringWidget( label=_(u"FacultyStaffDirectory_label_position", default=u"Position"), i18n_domain='FacultyStaffDirectory', ) ), StringField( name='title', widget=StringWidget( label=_(u"FacultyStaffDirectory_label_title", default=u"Title"), i18n_domain='FacultyStaffDirectory', visible={'edit': 'invisible', 'view': 'invisible' }, ) ), ), )
def modifyPersonOwnership(event): """Let people own their own objects and modify their own user preferences. Stolen from Plone and CMF core, but made less picky about where users are found. (and from borg, thanks, optilude!) """ context = event.context # Only run this if FSDPerson is an active membrane type. fsd_tool = getToolByName(context, 'facultystaffdirectory_tool') if 'FSDPerson' in fsd_tool.getEnableMembraneTypes(): catalog = getToolByName(context, 'portal_catalog') userId = IMembraneUserObject(context).getUserId() userFolder = getToolByName(context, 'acl_users') user = None while userFolder is not None: user = userFolder.getUserById(userId) if user is not None: break container = aq_parent(aq_inner(userFolder)) parent = aq_parent(aq_inner(container)) userFolder = getattr(parent, 'acl_users', None) if user is None: raise KeyError, _(u"User %s cannot be found.") % userId context.changeOwnership(user, False) def fixPersonRoles(context, userId): # Remove all other Owners of this Person object. Note that the creator will have an implicit # owner role. The User Preferences Editor role allows us to allow the user defined by the Person # to manage their own password and user preferences, but prevent the creator of the Person object # from modifying those fields. for owner in context.users_with_local_role('Owner'): roles = list(context.get_local_roles_for_userid(owner)) roles.remove('Owner') if roles: context.manage_setLocalRoles(owner, roles) else: context.manage_delLocalRoles([owner]) # Grant 'Owner' and 'User Preferences Editor' to the user defined by this object: roles = list(context.get_local_roles_for_userid(userId)) roles.extend(['Owner', u'Reviewer', 'User Preferences Editor']) # eliminate duplicated roles roles = list(set(roles)) context.manage_setLocalRoles(userId, roles) # Grant 'Owner' only to any users listed as 'assistants': for assistant in context.getReferences( relationship="people_assistants"): pid = assistant.id user = userFolder.getUserById(pid) if user is None: raise KeyError, _(u"User %s cannot be found.") % pid roles = list(context.get_local_roles_for_userid(pid)) roles.append('Owner') context.manage_setLocalRoles(pid, roles) fixPersonRoles(context, user.getId()) catalog.reindexObject(context)
from zope.interface import implements, classImplements try: from Products.Archetypes.Widget import TinyMCEWidget except ImportError: TinyMCEWidget = atapi.RichWidget logger = logging.getLogger('FacultyStaffDirectory') schema = ATContentTypeSchema.copy() + atapi.Schema(( atapi.StringField( name='firstName', widget=atapi.StringWidget( label=_(u"FacultyStaffDirectory_label_firstName", default=u"First Name"), i18n_domain='FacultyStaffDirectory', ), required=True, schemata="Basic Information", searchable=True ), atapi.StringField( name='middleName', widget=atapi.StringWidget( label=_(u"FacultyStaffDirectory_label_middleName", default=u"Middle Name"), i18n_domain='FacultyStaffDirectory', ), required=False, schemata="Basic Information",
from archetypes.referencebrowserwidget.widget import ReferenceBrowserWidget from Products.CMFCore.permissions import View, ManageProperties, ModifyPortalContent from Products.CMFCore.utils import getToolByName from zope.interface import implements from Products.CMFCore.permissions import ManageUsers from Products.membrane.at.interfaces import IPropertiesProvider from Products.FacultyStaffDirectory.interfaces.classification import IClassification from Acquisition import aq_inner, aq_parent from Products.FacultyStaffDirectory.permissions import ASSIGN_CLASSIFICATIONS_TO_PEOPLE from Products.FacultyStaffDirectory import FSDMessageFactory as _ from DateTime import DateTime schema = Schema( (RelationField(name='people', widget=ReferenceBrowserWidget( label=_(u"FacultyStaffDirectory_label_people", default=u"People"), i18n_domain='FacultyStaffDirectory', allow_browse=0, allow_search=1, show_results_without_query=1, base_query="_search_people_in_this_fsd", startup_directory_method="_get_parent_fsd_path", ), write_permission=ASSIGN_CLASSIFICATIONS_TO_PEOPLE, allowed_types=('FSDPerson', ), multiValued=1, relationship='classifications_people'), ), ) Classification_schema = getattr(PersonGrouping, 'schema', Schema( ())).copy() + schema.copy()
from Products.FacultyStaffDirectory.interfaces.person import IPerson from Products.FacultyStaffDirectory.interfaces.person import IPersonModifiedEvent from Products.FacultyStaffDirectory.interfaces.facultystaffdirectory import IFacultyStaffDirectory from Products.FacultyStaffDirectory.permissions import ASSIGN_CLASSIFICATIONS_TO_PEOPLE, ASSIGN_DEPARTMENTS_TO_PEOPLE, ASSIGN_COMMITTIES_TO_PEOPLE, ASSIGN_SPECIALTIES_TO_PEOPLE, CHANGE_PERSON_IDS from Products.FacultyStaffDirectory.validators import SequenceValidator from Products.FacultyStaffDirectory import FSDMessageFactory as _ logger = logging.getLogger('FacultyStaffDirectory') schema = ATContentTypeSchema.copy() + Schema(( StringField( name='firstName', widget=StringWidget( label=_(u"FacultyStaffDirectory_label_firstName", default=u"First Name"), i18n_domain='FacultyStaffDirectory', ), required=True, schemata="Basic Information", searchable=True ), StringField( name='middleName', widget=StringWidget( label=_(u"FacultyStaffDirectory_label_middleName", default=u"Middle Name"), i18n_domain='FacultyStaffDirectory', ), required=False, schemata="Basic Information",
from Products.CMFCore.utils import getToolByName from Products.FacultyStaffDirectory.interfaces.specialty import ISpecialty from Products.FacultyStaffDirectory.permissions import ASSIGN_SPECIALTIES_TO_PEOPLE from zope.interface import implements #from zope.i18nmessageid import MessageFactory #_ = MessageFactory('FacultyStaffDirectory') from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = Schema(( RelationField( name='people', widget=ReferenceBrowserWidget( label=_(u"FacultyStaffDirectory_label_people", default=u"People"), i18n_domain='FacultyStaffDirectory', allow_browse=0, allow_search=1, show_results_without_query=1, base_query="_search_people_in_this_fsd", startup_directory_method="_get_parent_fsd_path", ), write_permission=ASSIGN_SPECIALTIES_TO_PEOPLE, allowed_types=('FSDPerson',), multiValued=True, relationship='SpecialtyInformation' # weird relationship name is ArchGenXML's fault ), ImageField( name='overviewImage',
class Person(atapi.OrderedBaseFolder, ATCTContent): """A person in the Faculty/Staff directory""" meta_type = portal_type = "FSDPerson" security = ClassSecurityInfo() # zope3 interfaces implements(IPerson, IUserAuthProvider, IPropertiesProvider, IGroupsProvider, IGroupAwareRolesProvider, IAttributeAnnotatable, IUserChanger) # moved schema setting after finalizeATCTSchema, so the order of the fieldsets # is preserved. Also after updateActions is called since it seems to overwrite the schema # changes. # Move the description field, but not in Plone 2.5 since it's already in the metadata tab. # Although, # decription and relateditems are occasionally showing up in the "default" schemata. Move them # to "metadata" just to be safe. if 'categorization' in Person_schema.getSchemataNames(): Person_schema.changeSchemataForField('description', 'settings') else: Person_schema.changeSchemataForField('description', 'metadata') Person_schema.changeSchemataForField('relatedItems', 'metadata') # reorder the fields to move the dates into the employment information schemata along with the # termination details field and rename the effective and expiration dates. Person_schema['effectiveDate'].schemata = 'Employment Information' Person_schema['effectiveDate'].widget.label = _(u"label_edit_hire_date", default=u"Hire Date") Person_schema['effectiveDate'].widget.description = _( u"description_edit_hire_date", default=u"The date when the person will be hired. If no date is selected the person " u"will be considered hired immediately.") Person_schema['expirationDate'].schemata = 'Employment Information' Person_schema['expirationDate'].widget.label = _(u"label_edit_termination_date", default=u"Termination Date") Person_schema['expirationDate'].widget.description = _( u"description_edit_termination_date", default=u"The date when the person leaves the organization. This will automatically make " u"the person invisible for others at the given date.") Person_schema.moveField('effectiveDate', after='specialties') Person_schema.moveField('expirationDate', after='effectiveDate') Person_schema.moveField('terminationDetails', after='expirationDate') _at_rename_after_creation = True schema = Person_schema # Methods security.declareProtected(View, 'at_post_create_script') def at_post_create_script(self): """Notify that the Person has been modified. """ notify(PersonModifiedEvent(self)) security.declareProtected(View, 'at_post_edit_script') def at_post_edit_script(self): """Notify that the Person has been modified. """ notify(PersonModifiedEvent(self)) def __call__(self, *args, **kwargs): return self.getId() security.declareProtected(View, 'vcard_view') def vcard_view(self, REQUEST, RESPONSE): """vCard 3.0 output """ RESPONSE.setHeader('Content-Type', 'text/x-vcard') RESPONSE.setHeader('Content-Disposition', 'attachment; filename="%s.vcf"' % self.getId()) out = StringIO() # Get the fields using the accessors, so they're properly Unicode encoded. out.write("BEGIN:VCARD\nVERSION:3.0\n") out.write("FN:%s\n" % self.Title()) out.write("N:%s;%s\n" % (self.getLastName(), self.getFirstName())) out.write(foldLine("TITLE:%s\n" % '\\n'.join(self.getJobTitles()))) out.write(foldLine("ADR;TYPE=dom,postal,parcel,work:;;%s;%s;%s;%s\n" % ( self.getOfficeAddress().replace('\r\n', '\\n'), self.getOfficeCity(), self.getOfficeState(), self.getOfficePostalCode()))) out.write("TEL;WORK:%s\n" % self.getOfficePhone()) out.write("EMAIL;TYPE=internet:%s\n" % self.getEmail()) # Add the Person page to the list of URLs urls = list(self.getWebsites()) urls.append(self.absolute_url()) for url in urls: out.write(foldLine("URL:%s\n" % url)) if self.getImage(): encData = self.image_thumb.data.encode('base-64') # indent the data block: indentedData = '\n '.join(encData.strip().split('\n')) out.write("PHOTO;ENCODING=BASE64;TYPE=JPEG:\n %s\n" % indentedData) out.write("REV:%s\n" % DateTime(self.ModificationDate()).ISO8601()) out.write("PRODID:WebLion Faculty/Staff Directory\nEND:VCARD") return n2rn(out.getvalue()) security.declareProtected(View, 'getSortableName') def getSortableName(self): """ Return a tuple of the person's name. For sorting purposes Return them as lowercase so that names like 'von Whatever' sort properly """ return (self.lastName.lower(), self.firstName.lower()) security.declareProtected(View, 'Title') def Title(self): """ Return the Title as firstName middleName(when available) lastName, suffix(when available) """ try: # Get the fields using the accessors, so they're properly Unicode encoded. # We also can't use the %s method of string concatentation for the same reason. # Is there another way to manage this? fn = self.getFirstName() ln = self.getLastName() except AttributeError: # YTF doesn't this display on the New Person page? # Couldn't call superclass's Title() for some unknown reason return u"new person" if self.getMiddleName(): mn = " " + self.getMiddleName() + " " else: mn = " " t = fn + mn + ln if self.getSuffix(): t = t + ", " + self.getSuffix() return t security.declarePrivate('_classificationReferences') def _classificationReferences(self): """Return a list of Classifications this Person can be referenced to.""" return [(c.UID, safe_unicode(c.Title)) for c in self.aq_parent.getFolderContents({'portal_type': 'FSDClassification'})] security.declarePrivate('_availableEditors') def _availableEditors(self): """ Return a list of the available WYSIWYG editors for the site. """ try: props = getToolByName(self, 'portal_properties') editors = [ ('', 'Use site default') ] + [(e, e) for e in props['site_properties'].available_editors] except (AttributeError, KeyError): # plone 5 editors = [('tinymce', 'TinyMCE')] return editors security.declarePrivate('_availableLanguages') def _availableLanguages(self): """ Return a list of the available languages for the site. """ props = getToolByName(self, 'portal_properties') return props.availableLanguages() security.declarePrivate('_skinSelections') def _skinSelections(self): """ Return a list of the available skins for the site. """ skins = getToolByName(self, 'portal_skins') return skins.getSkinSelections() security.declareProtected(View, 'getCourses') def getCourses(self): """Return a listing of Courses contained by this Person.""" portal_catalog = getToolByName(self, 'portal_catalog') return portal_catalog( path='/'.join(self.getPhysicalPath()), portal_type='FSDCourse', depth=1, sort_on="getObjPositionInParent") security.declareProtected(View, 'getClassificationNames') def getClassificationNames(self): """ Returns a list of the titles of the classifications attached to this person. Mainly used for pretty-looking metadata in SmartFolder tables. """ cList = [(getObjPositionInParent(c)() + 1, c.Title()) for c in self.getClassifications()] cList.sort() return [c[-1] for c in cList] security.declareProtected(View, 'getSpecialtyTree') def getSpecialtyTree(self): """Return a tree-shaped dict of catalog brains of this person's specialties. The topmost level of the tree consists of SpecialtiesFolders; the remainder, of Specialties. The format of the dict is a superset of what buildFolderTree() returns (see its docstring for details). Consequently you can use a recursive macro similar to portlet_navtree_macro to render the results. Even if a person is mapped to a specialty but not to a superspecialty of it, the superspecialty will be returned. However, it will lack a 'reference' key, where explicitly mapped specialties will have one set to the reference from the Person to the Specialty. (All SpecialtiesFolders also lack 'reference' keys.) Thus, the template author can decide whether to consider people to implicitly belong to superspecialties of their explicitly mapped specialties, simply by deciding how to present the results. """ def buildSpecialtiesFolderTree(): """Return a buildFolderTree-style tree representing every SpecialtiesFolder and its descendents. More specifically, do a buildFolderTree for each SpecialtiesFolder, then merge the results into one big tree. """ portal_catalog = getToolByName(self, 'portal_catalog') tree = {'children': []} for specialtiesFolder in portal_catalog(portal_type='FSDSpecialtiesFolder'): subtree = buildFolderTree( self, query={'path': {'query': specialtiesFolder.getPath()}, 'portal_type': 'FSDSpecialty'}) subtree['currentItem'] = False subtree['currentParent'] = False subtree['item'] = specialtiesFolder subtree['depth'] = 0 # Let's see if that drives the stylesheets crazy. Otherwise, # I'm going to have to increment the 'depth' keys in the whole rest of the tree. tree['children'].append(subtree) return tree # Walk the tree, killing everything not in reffedUids, except for the ancestors of # reffed things. refs = getToolByName(self, 'reference_catalog').getReferences( self, relationship='people_specialties') reffedUids = dict([(ref.targetUID, ref) for ref in refs]) def pruneUnreffed(tree): """ Prune all subtrees from `tree` where no descendent is in `reffedUids`. Return whether `tree` itself should be pruned off. While we're at it, add 'reference' keys.""" keptChildren = [] for child in tree['children']: if not pruneUnreffed(child): # If that child shouldn't be completely pruned away, keptChildren.append(child) # keep it. tree['children'] = keptChildren if 'item' in tree: # 'item' is not in the root node. try: ref = reffedUids.get(tree['item'].UID) except TypeError: # Catch the 'unhashable type' error we're getting in rare cases # (seems to be mostly on uninstall/reinstall when catalog reindexing goes awry). ref = reffedUids.get(tree['item'].getObject().UID()) if ref: tree['reference'] = ref # I don't care if you pruned all my children off. I myself am reffed, # so I'm staying. return False # My children are the only thing keeping me here. # Prune me if there aren't any. (Sounds so dramatic, doesn't it?) return not keptChildren tree = buildSpecialtiesFolderTree() pruneUnreffed(tree) return tree security.declareProtected(View, 'getSpecialties') def getSpecialties(self): """Return an iterable of tuples representing the specialties explicitly attached to this person. The first item of the tuple is a catalog brain of a specialty; the second, the reference pointing from the Person to the Specialty. Results are ordered by the position of the specialties in their containers (SpecialtiesFolders or other Specialties) and by the order of SpecialtiesFolders themselves if there is more than one. To get a Specialties object from a result, call result.getTargetObject(). To get a SpecialtyInformation object, call result.getContentObject(). """ items = [] def depthFirst(tree): """ Append, in depth-first pre order, a tuple of ('item' value, 'reference' value) from `tree` for every node that has a 'reference' value.""" if 'reference' in tree: # There's always an 'item' key where there's a 'reference' key. # How can you have a reference if there's no item to reference? items.append((tree['item'], tree['reference'])) for child in tree['children']: depthFirst(child) depthFirst(self.getSpecialtyTree()) return items security.declareProtected(View, 'getSpecialtyNames') def getSpecialtyNames(self): """Return a list of the titles of the specialties explicitly attached to this person. Results are ordered as in getSpecialties(). Mainly used for pretty-looking metadata in SmartFolder tables. """ return [x.Title for x, _ in self.getSpecialties()] security.declareProtected(View, 'getResearchTopics') def getResearchTopics(self): """Return a list of the research topics of the specialties explicitly attached to this person. Results are ordered as in getSpecialties(). Specialties whose references have no content object (which doesn't happen) or where the content object has an empty research topic are omitted. Mainly used for pretty-looking metadata in SmartFolder tables. """ topics = [] for _, ref in self.getSpecialties(): # noqa # TODO: probably slow: wakes up all those SpecialtyInformation objects refContent = ref.getContentObject() # This is usually true, because reference-dwelling objects are always created when # the reference is created. However, it's false sometimes; run testSpecialties for # an example. if refContent: researchTopic = refContent.getResearchTopic() if researchTopic: topics.append(researchTopic) return topics security.declareProtected(View, 'getDepartmentNames') def getDepartmentNames(self): """ Returns a list of the titles of the departments attached to this person. Mainly used for pretty-looking metadata in SmartFolder tables. Returns an alphabetically-sorted list since Departments can be located anywhere within the site, which makes using any other sort order somewhat problematic. """ dList = [d.Title() for d in self.getDepartments()] dList.sort() return dList security.declareProtected(View, 'getCommitteeNames') def getCommitteeNames(self): """ Returns a list of the titles of the committees attached to this person. Mainly used for pretty-looking metadata in SmartFolder tables. Returns an alphabetically-sorted list since Committees can be located throughout the site, which makes using any other sort order somewhat problematic. """ dList = [d.Title() for d in self.getCommittees()] dList.sort() return dList security.declareProtected(ModifyPortalContent, 'pre_edit_setup') def pre_edit_setup(self): """ Some schema tweaking that needs to happen before viewing the edit page. """ fsd_tool = getToolByName(self, config.TOOLNAME) if (fsd_tool.getPhoneNumberRegex()): self.schema['officePhone'].widget.description = u"Example: %s" % ( fsd_tool.getPhoneNumberDescription()) if (fsd_tool.getIdLabel()): self.schema['id'].widget.label = u"%s" % fsd_tool.getIdLabel() # Make sure the default for the editor field is the same as the site defaut. # No idea why this isn't being handled properly. memberProps = getToolByName(self, 'portal_memberdata') self.schema['userpref_wysiwyg_editor'].default = memberProps.wysiwyg_editor return self.base_edit() security.declareProtected(View, 'tag') def tag(self, **kwargs): """Pass along the 'tag' method to the Person's image.""" return self.getWrappedField('image').tag(self, **kwargs) security.declareProtected(View, 'getImageOfSize') def getImageOfSize(self, height, width, **kwargs): """Return the person's image sized to the given dimensions.""" return self.getWrappedField('image').tag(self, width=width, height=height, **kwargs) security.declareProtected(View, 'getScaledImageByWidth') def getScaledImageByWidth(self, preferredWidth, **kwargs): """ Return the person's image sized to the given width and a height scaled according to the original image ratio. Fail nicely, returning no image tag. This seems to occur when TIFF images are used.""" if not (self.image.height or self.image.width): logger.error("There was an error resizing the image for person %s" % self) return '' hwratio = float(self.image.height)/float(self.image.width) calcHeight = int(preferredWidth * hwratio) return self.getImageOfSize(calcHeight, preferredWidth, **kwargs) security.declareProtected(ModifyPortalContent, 'setImage') def setImage(self, value, **kwargs): field = self.getField('image') # If the image exists in portal memberdata's portraits folder, delete it md = getToolByName(self, 'portal_memberdata') if self.id in md.portraits: md.portraits._delObject(self.id) # Assign the image to the field field.set(self, value) # If there is an image value (not the empty string that seems to get sent on # object creation) # and it's not a delete command, create a member portrait if value and value != 'DELETE_IMAGE': # Add the new portrait # md.portraits._setObject(id=self.id, object=self.getImage()) raw_image = StringIO() raw_image.write(str(self.getRawImage().data)) raw_image.seek(0) md.portraits._setObject(id=self.id, object=Image(id=self.id, file=raw_image, title='')) raw_image.close() security.declareProtected(SetOwnPassword, 'setPassword') def setPassword(self, value): """""" if value: annotations = IAnnotations(self) annotations[config.PASSWORD_KEY] = sha(value).digest() security.declareProtected(SetOwnPassword, 'setConfirmPassword') def setConfirmPassword(self, value): """""" # Do nothing - this value is used for verification only pass security.declarePrivate('validate_id') def validate_id(self, value): """ """ # Ensure the ID is unique in this folder: if value != self.getId(): parent = aq_parent(aq_inner(self)) if value in parent.objectIds(): return _(u"An object with ID '%s' already exists in this folder") % value # Make sure the ID fits the regex defined in the configuration: fsd_tool = getToolByName(self, config.TOOLNAME) regexString = fsd_tool.getIdRegex() if not re.match(regexString, value): return fsd_tool.getIdRegexErrorMessage() security.declarePrivate('validate_officePhone') def validate_officePhone(self, value=None): """ Make sure the phone number fits the regex defined in the configuration. """ if value: fsd_tool = getToolByName(self, config.TOOLNAME) regexString = fsd_tool.getPhoneNumberRegex() if regexString and not re.match(regexString, value): return _(u"Please provide the phone number in the format %s") % ( fsd_tool.getPhoneNumberDescription()) def spamProtectFSD(self, email): """ Implement a different email obfuscating approach than the standard Plone spam protection. Dots, @ etc. will be replaced with a string representation. """ email = email.replace('.', ' [ DOT ] ') email = email.replace('@', ' [ AT ] ') email = email.replace('-', ' [ DASH ] ') email = email.replace('_', ' [ UNDERSCORE ] ') return email security.declarePrivate('post_validate') def post_validate(self, REQUEST, errors): form = REQUEST.form if 'password' in form or 'confirmPassword' in form: password = form.get('password', None) confirm = form.get('confirmPassword', None) annotations = IAnnotations(self) passwordDigest = annotations.get(config.PASSWORD_KEY, None) if not passwordDigest: if not password and not confirm: errors['password'] = _(u'An initial password must be set') return if password or confirm: if password != confirm: errors['password'] = errors['confirmPassword'] = _(u'Passwords do not match') ### # Methods to limit the referenceBrowserWidget start directory and search results # security.declareProtected(ModifyPortalContent, '_get_parent_fsd_path') # def _get_parent_fsd_path(self): # """ wrap the utility method so we can use it in the context of an AT Schema declaration # """ # parent = aq_parent(aq_inner(self)) # if IFacultyStaffDirectory.providedBy(parent): # # we should pretty much always expect this to be true. People can't be added anywhere # # but inside an FSD, right at the FSD root, right? Is this a safe assumption? # return parent.absolute_url_path() # else: # return '/' security.declareProtected(ModifyPortalContent, '_get_parent_fsd_path') def _get_parent_fsd_path(self, relative=True): """ given an object of an FSD type, return the path to the parent FSD of that object """ url_tool = getToolByName(self, 'portal_url') # Walk up the tree until you find an FSD parent = aq_parent(aq_inner(self)) while not IPloneSiteRoot.providedBy(parent): if IFacultyStaffDirectory.providedBy(parent): if relative: # get the path relative to the portal root path = '/'.join(url_tool.getRelativeContentPath(parent)) else: # return the path starting with the portal root path = '/'.join(parent.getPhysicalPath()) return path else: parent = aq_parent(aq_inner(parent)) return "" security.declareProtected(ModifyPortalContent, '_limit_rbw_search_params') def _limit_rbw_search_params(self, portal_type="FSDPerson", sort_on="sortable_title"): """ return a query dictionary to limit the search parameters for a reference browser widget query. Use as basis for more specific versions below """ path = self._get_parent_fsd_path(relative=False) return {'portal_type': portal_type, 'sort_on': sort_on, 'path': {'query': path}} security.declareProtected(ModifyPortalContent, '_search_people_in_this_fsd') def _search_people_in_this_fsd(self): """ search only parent FSD for only people """ return self._limit_rbw_search_params(portal_type="FSDPerson") security.declareProtected(ModifyPortalContent, '_search_departments_in_this_fsd') def _search_departments_in_this_fsd(self): """ search only parent FSD for only departments """ return self._limit_rbw_search_params(portal_type="FSDDepartment") security.declareProtected(ModifyPortalContent, '_search_committees_in_this_fsd') def _search_committees_in_this_fsd(self): """ search only parent FSD for only committees """ return self._limit_rbw_search_params(portal_type="FSDCommittee") security.declareProtected(ModifyPortalContent, '_search_specialties_in_this_fsd') def _search_specialties_in_this_fsd(self): """ search only parent FSD for only specialties """ return self._limit_rbw_search_params(portal_type="FSDSpecialty")
def __init__(self, name, validator, description='', **kw): """Constructor validator - a validator (or ValidatorChain) to run against each item in the sequence. For reasonable results, make sure your chain cites the bad input in its error message. Otherwise, the user won't know what the error message applies to. """ self.name = name self.title = kw.get('title', name) self.description = description self.validator = validator def __call__(self, values, *args, **kwargs): errors = [self.validator(v) for v in values] errors = [x for x in errors if x not in (True, 1)] # Filter out non-errors. if errors: return '\n\n'.join(errors) else: # Not sure why this needs to be True, but returning 1 (like # RegexValidator) throws an Unsubscriptable Object exception. [Ed: # It's because that's what the IValidator interface proclaims. The # stock validators are just nonconformant.] return True classImplements(SequenceValidator, IValidator) # Change some error messages to improve grammar validation.validatorFor('isURL').errmsg = _(u'is not a valid URL.'),
from Products.membrane.utils import getFilteredValidRolesForPortal from Acquisition import aq_inner, aq_parent from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = ATContentTypeSchema.copy() + Schema(( LinesField( 'roles_', accessor='getRoles', mutator='setRoles', edit_accessor='getRawRoles', vocabulary='getRoleSet', default=['Member'], multiValued=1, write_permission=ManageUsers, widget=MultiSelectionWidget( label=_("FacultyStaffDirectory_label_FacultyStaffDirectoryRoles", default="Roles"), description=_( "FacultyStaffDirectory_description_FacultyStaffDirectoryRoles", default= "The roles all people in this directory will be granted site-wide" ), i18n_domain="FacultyStaffDirectory", ), ), IntegerField( 'personClassificationViewThumbnailWidth', accessor='getClassificationViewThumbnailWidth', mutator='setClassificationViewThumbnailWidth', schemata='Display', default=100, write_permission=ManageUsers,
}, pattern_options={ 'baseCriteria': [{ 'i': 'portal_type', 'o': 'plone.app.querystring.operation.string.is', 'v': 'FSDPerson', }], 'basePath': '', "contextPath": None, 'selectableTypes': [ 'FSDPerson', ], 'placeholder': _(u'Begin typing a name'), }, ), write_permission=ASSIGN_COMMITTIES_TO_PEOPLE, allowed_types=('FSDPerson', ), multiValued=True, relationship='CommitteeMembership'), ), ) Committee_schema = getattr(PersonGrouping, 'schema', Schema( ())).copy() + schema.copy() class Committee(PersonGrouping): """ """ security = ClassSecurityInfo()
from Products.FacultyStaffDirectory.interfaces.person import IPerson from Products.FacultyStaffDirectory.interfaces.person import IPersonModifiedEvent from Products.FacultyStaffDirectory.interfaces.facultystaffdirectory import IFacultyStaffDirectory from Products.FacultyStaffDirectory.permissions import ASSIGN_CLASSIFICATIONS_TO_PEOPLE, ASSIGN_DEPARTMENTS_TO_PEOPLE, ASSIGN_LABS_TO_PEOPLE,ASSIGN_COMMITTIES_TO_PEOPLE, ASSIGN_SPECIALTIES_TO_PEOPLE, CHANGE_PERSON_IDS from Products.FacultyStaffDirectory.validators import SequenceValidator from Products.FacultyStaffDirectory import FSDMessageFactory as _ logger = logging.getLogger('FacultyStaffDirectory') schema = ATContentTypeSchema.copy() + Schema(( StringField( name='firstName', widget=StringWidget( label=_(u"FacultyStaffDirectory_label_firstName", default=u"First Name"), i18n_domain='FacultyStaffDirectory', ), required=True, schemata="Basic Information", searchable=True ), StringField( name='middleName', widget=StringWidget( label=_(u"FacultyStaffDirectory_label_middleName", default=u"Middle Name"), i18n_domain='FacultyStaffDirectory', ), required=False, schemata="Basic Information",
from Products.CMFCore.utils import getToolByName from Products.FacultyStaffDirectory.interfaces.specialty import ISpecialty from Products.FacultyStaffDirectory.permissions import ASSIGN_SPECIALTIES_TO_PEOPLE from zope.interface import implements #from zope.i18nmessageid import MessageFactory #_ = MessageFactory('FacultyStaffDirectory') from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = Schema( ( RelationField( name='people', widget=ReferenceBrowserWidget( label=_(u"FacultyStaffDirectory_label_people", default=u"People"), i18n_domain='FacultyStaffDirectory', allow_browse=0, allow_search=1, show_results_without_query=1, base_query="_search_people_in_this_fsd", startup_directory_method="_get_parent_fsd_path", ), write_permission=ASSIGN_SPECIALTIES_TO_PEOPLE, allowed_types=('FSDPerson', ), multiValued=True, relationship= 'SpecialtyInformation' # weird relationship name is ArchGenXML's fault ), ImageField( name='overviewImage',
from Products.ATReferenceBrowserWidget.ATReferenceBrowserWidget import ReferenceBrowserWidget from Products.CMFCore.permissions import View from Products.FacultyStaffDirectory.PersonGrouping import PersonGrouping from Products.Relations.field import RelationField from Products.FacultyStaffDirectory.config import * from Products.CMFCore.utils import getToolByName from Products.FacultyStaffDirectory.interfaces.lab import ILab from zope.interface import implements from Products.FacultyStaffDirectory.permissions import ASSIGN_LABS_TO_PEOPLE from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = Schema(( StringField( name="lab_short_name", widget=StringWidget( label=_(u"FacultyStaffDirectory_label_labshort", default=u"Lab Short Name"), description=_(u"FacultyStaffDirectory_description_labshort", default=u""), i18n_domain='FacultyStaffDirectory', ), required=False, allow_search=1, ), StringField( name='dept_url', widget=StringWidget( label=_(u"FacultyStaffDirectory_label_labUrl", default=u"Primary Lab URL"), description=_(u"FacultyStaffDirectory_description_laburl", default=u""), i18n_domain='FacultyStaffDirectory', ), validators = ('isURL')
show_indexes = False, force_close_on_insert = True, label = u"Members", label_msgid = "FacultyStaffDirectory_label_members", i18n_domain = "FacultyStaffDirectory", visible = {'edit' : 'visible', 'view' : 'visible' }, pattern_options={ 'baseCriteria': [{ 'i': 'portal_type', 'o': 'plone.app.querystring.operation.string.is', 'v': 'FSDPerson', }], 'basePath': '', "contextPath": None, 'selectableTypes': ['FSDPerson', ], 'placeholder': _(u'Begin typing a name'), }, ), write_permission=ASSIGN_DEPARTMENTS_TO_PEOPLE, allowed_types=('FSDPerson',), multiValued=1, relationship='departments_members' ), ), ) Department_schema = getattr(PersonGrouping, 'schema', Schema(())).copy() + schema.copy() class Department(PersonGrouping): """ """
from Products.ATReferenceBrowserWidget.ATReferenceBrowserWidget import ReferenceBrowserWidget from Products.CMFCore.permissions import View from Products.FacultyStaffDirectory.PersonGrouping import PersonGrouping from Products.Relations.field import RelationField from Products.FacultyStaffDirectory.config import * from Products.CMFCore.utils import getToolByName from Products.FacultyStaffDirectory.interfaces.lab import ILab from zope.interface import implements from Products.FacultyStaffDirectory.permissions import ASSIGN_LABS_TO_PEOPLE from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = Schema(( StringField( name="lab_short_name", widget=StringWidget( label=_(u"FacultyStaffDirectory_label_labshort", default=u"Lab Short Name"), description=_(u"FacultyStaffDirectory_description_labshort", default=u""), i18n_domain='FacultyStaffDirectory', ), required=False, allow_search=1, ), StringField(name='dept_url', widget=StringWidget( label=_(u"FacultyStaffDirectory_label_labUrl", default=u"Primary Lab URL"), description=_(u"FacultyStaffDirectory_description_laburl", default=u""), i18n_domain='FacultyStaffDirectory', ),
from Products.CMFCore.permissions import View from Products.FacultyStaffDirectory.PersonGrouping import PersonGrouping from Products.Relations.field import RelationField from Products.FacultyStaffDirectory.config import * from Products.CMFCore.utils import getToolByName from Products.FacultyStaffDirectory.interfaces.department import IDepartment from zope.interface import implements from Products.FacultyStaffDirectory.permissions import ASSIGN_DEPARTMENTS_TO_PEOPLE from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = Schema(( StringField( name="dept_short_name", widget=StringWidget( label=_(u"FacultyStaffDirectory_label_deptshort", default=u"Department Short Name"), description=_(u"FacultyStaffDirectory_description_officePhone", default=u""), i18n_domain='FacultyStaffDirectory', ), required=False, allow_search=1, ), StringField( name='dept_url', widget=StringWidget( label=_(u"FacultyStaffDirectory_label_deptUrl", default=u"Primary Department URL"), description=_(u"FacultyStaffDirectory_description_depturl", default=u""), i18n_domain='FacultyStaffDirectory', ), validators = ('isURL')
from Products.ATReferenceBrowserWidget.ATReferenceBrowserWidget import ReferenceBrowserWidget from Products.CMFCore.permissions import View from Products.FacultyStaffDirectory.PersonGrouping import PersonGrouping from Products.Relations.field import RelationField from Products.FacultyStaffDirectory.config import * from Products.CMFCore.utils import getToolByName from Products.FacultyStaffDirectory.interfaces.department import IDepartment from zope.interface import implements from Products.FacultyStaffDirectory.permissions import ASSIGN_DEPARTMENTS_TO_PEOPLE from Products.FacultyStaffDirectory import FSDMessageFactory as _ schema = Schema(( StringField( name="dept_short_name", widget=StringWidget( label=_(u"FacultyStaffDirectory_label_deptshort", default=u"Department Short Name"), description=_(u"FacultyStaffDirectory_description_officePhone", default=u""), i18n_domain='FacultyStaffDirectory', ), required=False, allow_search=1, ), StringField(name='dept_url', widget=StringWidget( label=_(u"FacultyStaffDirectory_label_deptUrl", default=u"Primary Department URL"), description=_(u"FacultyStaffDirectory_description_depturl", default=u""), i18n_domain='FacultyStaffDirectory', ),