Source code for ploneintranet.userprofile.content.userprofile

# coding=utf-8
from collective import dexteritytextindexer
from plone import api as plone_api
from plone.autoform import directives
from plone.autoform.interfaces import IFormFieldProvider
from plone.dexterity.content import Container
from plone.namedfile.field import NamedBlobImage
from plone.supermodel import model
from ploneintranet.core import ploneintranetCoreMessageFactory as _
from Products.CMFPlone.utils import safe_unicode
from z3c.form import validator
from zope import schema
from zope.interface import implementer
from zope.interface import Invalid
from zope.interface import provider


[docs]class Email(schema.TextLine): """ An email field """
[docs]class Phone(schema.TextLine): """ A phone field """
[docs]class GooglePlace(schema.Choice): """ A field that is linked in the display view to a google place search """
[docs]class IUserProfile(model.Schema): """The core user profile schema. Most of the plone intranet UI relies on these fields. """ # username == context.getId() == userid # username should never be changed because it's used as an alias for userid # if you need different login names, switch on use_email_as_username # see changeset and docs in quaive/ploneintranet#1043 dexteritytextindexer.searchable("username") username = schema.TextLine(title=_(u"Username"), required=True, default=u"") dexteritytextindexer.searchable("person_title") person_title = schema.TextLine( title=_(u"Person title"), required=False, default=u"" ) dexteritytextindexer.searchable("first_name") first_name = schema.TextLine(title=_(u"First name"), required=True, default=u"") dexteritytextindexer.searchable("last_name") last_name = schema.TextLine(title=_(u"Last name"), required=True, default=u"") dexteritytextindexer.searchable("email") email = Email(title=_(u"Email"), required=True, default=u"") portrait = NamedBlobImage(title=_(u"Photo"), required=False, default=None) directives.omitted("recent_contacts") recent_contacts = schema.List(title=_("Last Contacts"), required=False, default=[])
[docs]@provider(IFormFieldProvider) class IUserProfileAdditional(model.Schema): """Default additional fields for UserProfile.""" dexteritytextindexer.searchable("job_title") job_title = schema.TextLine(title=_(u"Job title"), required=False, default=u"") dexteritytextindexer.searchable("department") department = schema.TextLine(title=_(u"Department"), required=False, default=u"") dexteritytextindexer.searchable("telephone") telephone = Phone(title=_(u"Telephone Number"), required=False, default=u"") dexteritytextindexer.searchable("mobile") mobile = Phone(title=_(u"Mobile Number"), required=False, default=u"") dexteritytextindexer.searchable("address") address = schema.Text(title=_(u"Address"), required=False, default=u"") time_zone = schema.Choice( title=_(u"Time Zone"), source=u"plone.app.vocabularies.CommonTimezones", required=False, ) primary_location = GooglePlace( title=_(u"Primary location"), source=u"ploneintranet.userprofile.locations_vocabulary", required=False, ) dexteritytextindexer.searchable("biography") biography = schema.Text(title=_(u"Biography"), required=False, default=u"")
[docs]@implementer(IUserProfile) class UserProfile(Container): """UserProfile content type."""
[docs] def Title(self): return self.fullname
[docs] def Description(self): return getattr(self, "job_title", None)
@property def fullname(self): names = [self.person_title, self.first_name, self.last_name] return u" ".join([name for name in names if name]) @property def initials(self): first_name = self.first_name or "" last_name = self.last_name or "" return first_name[:1].upper() + last_name[:2].capitalize() @property def display_name_email(self): if not self.email: return "" return u"{} <{}>".format( safe_unicode(self.fullname or self.email), safe_unicode(self.email) )
[docs]class UsernameValidator(validator.SimpleFieldValidator): """Two users can't have the same username. Because of #1043 it's possible that .username != .getUserName() so instead we rely on .username == .getUserId() which holds true since we don't do use_uuid_as_userid. """
[docs] def validate(self, value, force=False): membrane_tool = plone_api.portal.get_tool("membrane_tool") usernames = membrane_tool._catalog.uniqueValuesFor("exact_getUserId") if value in usernames: brains = membrane_tool.searchResults(exact_getUserId=value) if brains and self.context != brains[0].getObject(): raise Invalid(_("A user with this username already exists")) return super(UsernameValidator, self).validate(value)
validator.WidgetValidatorDiscriminators( UsernameValidator, field=IUserProfile["username"] )