We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Author feedback form broken
Author feedback seems to have been missed in the refactoring of settings into the registry. It stills expects to find portal.email_from_name


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `Products/CMFPlone/browser/author.py`
Content:
```
1 from AccessControl import Unauthorized
2 
3 from Products.CMFCore.interfaces import IPropertiesTool
4 from Products.CMFPlone import PloneMessageFactory as _
5 from Products.CMFPlone.interfaces import ISecuritySchema
6 from Products.CMFPlone.interfaces.controlpanel import IMailSchema
7 from Products.CMFPlone.utils import getToolByName
8 from Products.CMFPlone.utils import pretty_title_or_id
9 from Products.Five.browser import BrowserView
10 from Products.MailHost.interfaces import IMailHost
11 from Products.statusmessages.interfaces import IStatusMessage
12 
13 from ZODB.POSException import ConflictError
14 
15 from interfaces import IAuthorFeedbackForm
16 
17 from plone.registry.interfaces import IRegistry
18 
19 from urllib import quote_plus
20 
21 from z3c.form import button
22 from z3c.form import field
23 from z3c.form import form
24 from z3c.form.interfaces import HIDDEN_MODE
25 
26 from zope.component import getMultiAdapter
27 from zope.component import getUtility
28 from zope.interface import implementer
29 from zope.publisher.interfaces import IPublishTraverse
30 
31 import logging
32 
33 logger = logging.getLogger("Plone")
34 
35 
36 class AuthorFeedbackForm(form.Form):
37 
38     fields = field.Fields(IAuthorFeedbackForm)
39     ignoreContext = True
40 
41     @button.buttonAndHandler(_(u'label_send', default='Send'),
42                              name='send')
43     def handle_send(self, action):
44         self.portal_state = getMultiAdapter(
45             (self.context, self.request),
46             name=u'plone_portal_state'
47         )
48 
49         self.portal = self.portal_state.portal()
50         self.membership_tool = getToolByName(
51             self.context, 'portal_membership'
52         )
53 
54         self.feedback_template = self.context.restrictedTraverse(
55             '@@author-feedback-template'
56         )
57 
58         data, errors = self.extractData()
59         if errors:
60             IStatusMessage(self.request).addStatusMessage(
61                 self.formErrorsMessage,
62                 type=u'error'
63             )
64 
65             return
66 
67         referer = data.get('referer', 'unknown referer')
68         subject = data.get('subject', '')
69         message = data.get('message', '')
70         # Author is None means portal administrator
71         author = data.get('author', None)
72 
73         sender = self.portal_state.member()
74         registry = getUtility(IRegistry)
75         mail_settings = registry.forInterface(IMailSchema, prefix='plone')
76         envelope_from = mail_settings.email_from_address
77 
78         if author is None:
79             send_to_address = mail_settings.email_from_address
80         else:
81             author_member = self.membership_tool.getMemberById(author)
82             send_to_address = author_member.getProperty('email')
83 
84         send_from_address = sender.getProperty('email')
85 
86         if send_from_address == '':
87             IStatusMessage(self.request).addStatusMessage(
88                 _(u'Could not find a valid email address'),
89                 type=u'error'
90             )
91             return
92 
93         sender_id = "%s (%s), %s" % (
94             sender.getProperty('fullname'),
95             sender.getId(),
96             send_from_address
97         )
98 
99         mail_host = getUtility(IMailHost)
100         registry = getUtility(IRegistry)
101         email_charset = registry.get('plone.email_charset', 'utf-8')
102 
103         try:
104             message = self.feedback_template(
105                 self, send_from_address=send_from_address,
106                 sender_id=sender_id, url=referer, subject=subject,
107                 message=message, encoding=email_charset
108             )
109 
110             message = message.encode(email_charset)
111 
112             mail_host.send(
113                 message, send_to_address, envelope_from,
114                 subject=subject, charset=email_charset
115             )
116         except ConflictError:
117             raise
118         except Exception as e:
119             logger.info("Unable to send mail: " + str(e))
120 
121             IStatusMessage(self.request).addStatusMessage(
122                 _(u'Unable to send mail.'),
123                 type=u'error'
124             )
125 
126             return
127 
128         IStatusMessage(self.request).addStatusMessage(
129             _(u'Mail sent.'),
130             type=u'info'
131         )
132         self.request.response.redirect('%s/author/%s' % (
133             self.portal.absolute_url(),
134             author or ''))
135         return
136 
137 
138 @implementer(IPublishTraverse)
139 class AuthorView(BrowserView):
140 
141     def __init__(self, context, request):
142         super(AuthorView, self).__init__(context, request)
143 
144         self.username = None
145 
146     def publishTraverse(self, request, name):
147         request['TraversalRequestNameStack'] = []
148 
149         self.username = name
150         return self
151 
152     @property
153     def is_anonymous(self):
154         return self.portal_state.anonymous()
155 
156     @property
157     def is_owner(self):
158         current_member = self.portal_state.member()
159         return current_member.getId() == self.username
160 
161     @property
162     def author(self):
163         username = self.username
164 
165         if not username:
166             return {}
167 
168         authorinfo = self.membership_tool.getMemberInfo(username)
169         portrait = self.membership_tool.getPersonalPortrait(username)
170 
171         if not authorinfo or not portrait:
172             return {}
173 
174         return {
175             'info': authorinfo,
176             'portrait': portrait
177         }
178 
179     @property
180     def member_info(self):
181         current_member = self.portal_state.member()
182         if not current_member or not current_member.getId():
183             return {'url': None, 'email': None}
184 
185         return {
186             'url': quote_plus(current_member.getId()),
187             'email': current_member.getProperty('email')
188         }
189 
190     @property
191     def author_content(self):
192         results = []
193 
194         plone_view = self.context.restrictedTraverse(
195             '@@plone'
196         )
197 
198         brains = self.portal_catalog.searchResults(
199             Creator=self.username,
200             sort_on='created',
201             sort_order='reverse'
202         )
203 
204         for brain in brains[:10]:
205             results.append({
206                 'title': pretty_title_or_id(
207                     self, brain
208                 ),
209                 'date': plone_view.toLocalizedTime(
210                     brain.Date
211                 ),
212                 'url': brain.getURL()
213             })
214 
215         return results
216 
217     def home_folder(self, username):
218         return self.membership_tool.getHomeFolder(id=username)
219 
220     def __call__(self):
221 
222         self.portal_properties = getUtility(
223             IPropertiesTool
224         )
225 
226         self.portal_catalog = getToolByName(
227             self.context, 'portal_catalog'
228         )
229 
230         # XXX: getUtility call does not work.
231         self.membership_tool = getToolByName(
232             self.context, 'portal_membership'
233         )
234 
235         self.portal_state = getMultiAdapter(
236             (self.context, self.request),
237             name=u'plone_portal_state'
238         )
239 
240         self.feedback_form = AuthorFeedbackForm(
241             self.context, self.request
242         )
243         self.feedback_form.update()
244         self.feedback_form.widgets["author"].mode = HIDDEN_MODE
245         self.feedback_form.widgets["referer"].mode = HIDDEN_MODE
246         self.feedback_form.widgets["author"].value = self.username
247         self.feedback_form.widgets["referer"].value = self.request.get(
248             'referer',
249             self.request.get('HTTP_REFERER', 'unknown url')
250         )
251 
252         registry = getUtility(IRegistry)
253         security_settings = registry.forInterface(
254             ISecuritySchema, prefix='plone')
255         allow_anonymous_view_about = security_settings.allow_anon_views_about
256 
257         mail_settings = registry.forInterface(IMailSchema, prefix='plone')
258         self.email_from_address = mail_settings.email_from_address
259 
260         if self.is_anonymous and not allow_anonymous_view_about:
261             raise Unauthorized()
262 
263         return self.index()
264
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/Products/CMFPlone/browser/author.py b/Products/CMFPlone/browser/author.py
--- a/Products/CMFPlone/browser/author.py
+++ b/Products/CMFPlone/browser/author.py
@@ -104,7 +104,8 @@
             message = self.feedback_template(
                 self, send_from_address=send_from_address,
                 sender_id=sender_id, url=referer, subject=subject,
-                message=message, encoding=email_charset
+                message=message, encoding=email_charset,
+                email_from_name=mail_settings.email_from_name
             )
 
             message = message.encode(email_charset)

{"golden_diff": "diff --git a/Products/CMFPlone/browser/author.py b/Products/CMFPlone/browser/author.py\n--- a/Products/CMFPlone/browser/author.py\n+++ b/Products/CMFPlone/browser/author.py\n@@ -104,7 +104,8 @@\n             message = self.feedback_template(\n                 self, send_from_address=send_from_address,\n                 sender_id=sender_id, url=referer, subject=subject,\n-                message=message, encoding=email_charset\n+                message=message, encoding=email_charset,\n+                email_from_name=mail_settings.email_from_name\n             )\n \n             message = message.encode(email_charset)\n", "issue": "Author feedback form broken\nAuthor feedback seems to have been missed in the refactoring of settings into the registry. It stills expects to find portal.email_from_name\n\n", "before_files": [{"content": "from AccessControl import Unauthorized\n\nfrom Products.CMFCore.interfaces import IPropertiesTool\nfrom Products.CMFPlone import PloneMessageFactory as _\nfrom Products.CMFPlone.interfaces import ISecuritySchema\nfrom Products.CMFPlone.interfaces.controlpanel import IMailSchema\nfrom Products.CMFPlone.utils import getToolByName\nfrom Products.CMFPlone.utils import pretty_title_or_id\nfrom Products.Five.browser import BrowserView\nfrom Products.MailHost.interfaces import IMailHost\nfrom Products.statusmessages.interfaces import IStatusMessage\n\nfrom ZODB.POSException import ConflictError\n\nfrom interfaces import IAuthorFeedbackForm\n\nfrom plone.registry.interfaces import IRegistry\n\nfrom urllib import quote_plus\n\nfrom z3c.form import button\nfrom z3c.form import field\nfrom z3c.form import form\nfrom z3c.form.interfaces import HIDDEN_MODE\n\nfrom zope.component import getMultiAdapter\nfrom zope.component import getUtility\nfrom zope.interface import implementer\nfrom zope.publisher.interfaces import IPublishTraverse\n\nimport logging\n\nlogger = logging.getLogger(\"Plone\")\n\n\nclass AuthorFeedbackForm(form.Form):\n\n    fields = field.Fields(IAuthorFeedbackForm)\n    ignoreContext = True\n\n    @button.buttonAndHandler(_(u'label_send', default='Send'),\n                             name='send')\n    def handle_send(self, action):\n        self.portal_state = getMultiAdapter(\n            (self.context, self.request),\n            name=u'plone_portal_state'\n        )\n\n        self.portal = self.portal_state.portal()\n        self.membership_tool = getToolByName(\n            self.context, 'portal_membership'\n        )\n\n        self.feedback_template = self.context.restrictedTraverse(\n            '@@author-feedback-template'\n        )\n\n        data, errors = self.extractData()\n        if errors:\n            IStatusMessage(self.request).addStatusMessage(\n                self.formErrorsMessage,\n                type=u'error'\n            )\n\n            return\n\n        referer = data.get('referer', 'unknown referer')\n        subject = data.get('subject', '')\n        message = data.get('message', '')\n        # Author is None means portal administrator\n        author = data.get('author', None)\n\n        sender = self.portal_state.member()\n        registry = getUtility(IRegistry)\n        mail_settings = registry.forInterface(IMailSchema, prefix='plone')\n        envelope_from = mail_settings.email_from_address\n\n        if author is None:\n            send_to_address = mail_settings.email_from_address\n        else:\n            author_member = self.membership_tool.getMemberById(author)\n            send_to_address = author_member.getProperty('email')\n\n        send_from_address = sender.getProperty('email')\n\n        if send_from_address == '':\n            IStatusMessage(self.request).addStatusMessage(\n                _(u'Could not find a valid email address'),\n                type=u'error'\n            )\n            return\n\n        sender_id = \"%s (%s), %s\" % (\n            sender.getProperty('fullname'),\n            sender.getId(),\n            send_from_address\n        )\n\n        mail_host = getUtility(IMailHost)\n        registry = getUtility(IRegistry)\n        email_charset = registry.get('plone.email_charset', 'utf-8')\n\n        try:\n            message = self.feedback_template(\n                self, send_from_address=send_from_address,\n                sender_id=sender_id, url=referer, subject=subject,\n                message=message, encoding=email_charset\n            )\n\n            message = message.encode(email_charset)\n\n            mail_host.send(\n                message, send_to_address, envelope_from,\n                subject=subject, charset=email_charset\n            )\n        except ConflictError:\n            raise\n        except Exception as e:\n            logger.info(\"Unable to send mail: \" + str(e))\n\n            IStatusMessage(self.request).addStatusMessage(\n                _(u'Unable to send mail.'),\n                type=u'error'\n            )\n\n            return\n\n        IStatusMessage(self.request).addStatusMessage(\n            _(u'Mail sent.'),\n            type=u'info'\n        )\n        self.request.response.redirect('%s/author/%s' % (\n            self.portal.absolute_url(),\n            author or ''))\n        return\n\n\n@implementer(IPublishTraverse)\nclass AuthorView(BrowserView):\n\n    def __init__(self, context, request):\n        super(AuthorView, self).__init__(context, request)\n\n        self.username = None\n\n    def publishTraverse(self, request, name):\n        request['TraversalRequestNameStack'] = []\n\n        self.username = name\n        return self\n\n    @property\n    def is_anonymous(self):\n        return self.portal_state.anonymous()\n\n    @property\n    def is_owner(self):\n        current_member = self.portal_state.member()\n        return current_member.getId() == self.username\n\n    @property\n    def author(self):\n        username = self.username\n\n        if not username:\n            return {}\n\n        authorinfo = self.membership_tool.getMemberInfo(username)\n        portrait = self.membership_tool.getPersonalPortrait(username)\n\n        if not authorinfo or not portrait:\n            return {}\n\n        return {\n            'info': authorinfo,\n            'portrait': portrait\n        }\n\n    @property\n    def member_info(self):\n        current_member = self.portal_state.member()\n        if not current_member or not current_member.getId():\n            return {'url': None, 'email': None}\n\n        return {\n            'url': quote_plus(current_member.getId()),\n            'email': current_member.getProperty('email')\n        }\n\n    @property\n    def author_content(self):\n        results = []\n\n        plone_view = self.context.restrictedTraverse(\n            '@@plone'\n        )\n\n        brains = self.portal_catalog.searchResults(\n            Creator=self.username,\n            sort_on='created',\n            sort_order='reverse'\n        )\n\n        for brain in brains[:10]:\n            results.append({\n                'title': pretty_title_or_id(\n                    self, brain\n                ),\n                'date': plone_view.toLocalizedTime(\n                    brain.Date\n                ),\n                'url': brain.getURL()\n            })\n\n        return results\n\n    def home_folder(self, username):\n        return self.membership_tool.getHomeFolder(id=username)\n\n    def __call__(self):\n\n        self.portal_properties = getUtility(\n            IPropertiesTool\n        )\n\n        self.portal_catalog = getToolByName(\n            self.context, 'portal_catalog'\n        )\n\n        # XXX: getUtility call does not work.\n        self.membership_tool = getToolByName(\n            self.context, 'portal_membership'\n        )\n\n        self.portal_state = getMultiAdapter(\n            (self.context, self.request),\n            name=u'plone_portal_state'\n        )\n\n        self.feedback_form = AuthorFeedbackForm(\n            self.context, self.request\n        )\n        self.feedback_form.update()\n        self.feedback_form.widgets[\"author\"].mode = HIDDEN_MODE\n        self.feedback_form.widgets[\"referer\"].mode = HIDDEN_MODE\n        self.feedback_form.widgets[\"author\"].value = self.username\n        self.feedback_form.widgets[\"referer\"].value = self.request.get(\n            'referer',\n            self.request.get('HTTP_REFERER', 'unknown url')\n        )\n\n        registry = getUtility(IRegistry)\n        security_settings = registry.forInterface(\n            ISecuritySchema, prefix='plone')\n        allow_anonymous_view_about = security_settings.allow_anon_views_about\n\n        mail_settings = registry.forInterface(IMailSchema, prefix='plone')\n        self.email_from_address = mail_settings.email_from_address\n\n        if self.is_anonymous and not allow_anonymous_view_about:\n            raise Unauthorized()\n\n        return self.index()\n", "path": "Products/CMFPlone/browser/author.py"}], "after_files": [{"content": "from AccessControl import Unauthorized\n\nfrom Products.CMFCore.interfaces import IPropertiesTool\nfrom Products.CMFPlone import PloneMessageFactory as _\nfrom Products.CMFPlone.interfaces import ISecuritySchema\nfrom Products.CMFPlone.interfaces.controlpanel import IMailSchema\nfrom Products.CMFPlone.utils import getToolByName\nfrom Products.CMFPlone.utils import pretty_title_or_id\nfrom Products.Five.browser import BrowserView\nfrom Products.MailHost.interfaces import IMailHost\nfrom Products.statusmessages.interfaces import IStatusMessage\n\nfrom ZODB.POSException import ConflictError\n\nfrom interfaces import IAuthorFeedbackForm\n\nfrom plone.registry.interfaces import IRegistry\n\nfrom urllib import quote_plus\n\nfrom z3c.form import button\nfrom z3c.form import field\nfrom z3c.form import form\nfrom z3c.form.interfaces import HIDDEN_MODE\n\nfrom zope.component import getMultiAdapter\nfrom zope.component import getUtility\nfrom zope.interface import implementer\nfrom zope.publisher.interfaces import IPublishTraverse\n\nimport logging\n\nlogger = logging.getLogger(\"Plone\")\n\n\nclass AuthorFeedbackForm(form.Form):\n\n    fields = field.Fields(IAuthorFeedbackForm)\n    ignoreContext = True\n\n    @button.buttonAndHandler(_(u'label_send', default='Send'),\n                             name='send')\n    def handle_send(self, action):\n        self.portal_state = getMultiAdapter(\n            (self.context, self.request),\n            name=u'plone_portal_state'\n        )\n\n        self.portal = self.portal_state.portal()\n        self.membership_tool = getToolByName(\n            self.context, 'portal_membership'\n        )\n\n        self.feedback_template = self.context.restrictedTraverse(\n            '@@author-feedback-template'\n        )\n\n        data, errors = self.extractData()\n        if errors:\n            IStatusMessage(self.request).addStatusMessage(\n                self.formErrorsMessage,\n                type=u'error'\n            )\n\n            return\n\n        referer = data.get('referer', 'unknown referer')\n        subject = data.get('subject', '')\n        message = data.get('message', '')\n        # Author is None means portal administrator\n        author = data.get('author', None)\n\n        sender = self.portal_state.member()\n        registry = getUtility(IRegistry)\n        mail_settings = registry.forInterface(IMailSchema, prefix='plone')\n        envelope_from = mail_settings.email_from_address\n\n        if author is None:\n            send_to_address = mail_settings.email_from_address\n        else:\n            author_member = self.membership_tool.getMemberById(author)\n            send_to_address = author_member.getProperty('email')\n\n        send_from_address = sender.getProperty('email')\n\n        if send_from_address == '':\n            IStatusMessage(self.request).addStatusMessage(\n                _(u'Could not find a valid email address'),\n                type=u'error'\n            )\n            return\n\n        sender_id = \"%s (%s), %s\" % (\n            sender.getProperty('fullname'),\n            sender.getId(),\n            send_from_address\n        )\n\n        mail_host = getUtility(IMailHost)\n        registry = getUtility(IRegistry)\n        email_charset = registry.get('plone.email_charset', 'utf-8')\n\n        try:\n            message = self.feedback_template(\n                self, send_from_address=send_from_address,\n                sender_id=sender_id, url=referer, subject=subject,\n                message=message, encoding=email_charset,\n                email_from_name=mail_settings.email_from_name\n            )\n\n            message = message.encode(email_charset)\n\n            mail_host.send(\n                message, send_to_address, envelope_from,\n                subject=subject, charset=email_charset\n            )\n        except ConflictError:\n            raise\n        except Exception as e:\n            logger.info(\"Unable to send mail: \" + str(e))\n\n            IStatusMessage(self.request).addStatusMessage(\n                _(u'Unable to send mail.'),\n                type=u'error'\n            )\n\n            return\n\n        IStatusMessage(self.request).addStatusMessage(\n            _(u'Mail sent.'),\n            type=u'info'\n        )\n        self.request.response.redirect('%s/author/%s' % (\n            self.portal.absolute_url(),\n            author or ''))\n        return\n\n\n@implementer(IPublishTraverse)\nclass AuthorView(BrowserView):\n\n    def __init__(self, context, request):\n        super(AuthorView, self).__init__(context, request)\n\n        self.username = None\n\n    def publishTraverse(self, request, name):\n        request['TraversalRequestNameStack'] = []\n\n        self.username = name\n        return self\n\n    @property\n    def is_anonymous(self):\n        return self.portal_state.anonymous()\n\n    @property\n    def is_owner(self):\n        current_member = self.portal_state.member()\n        return current_member.getId() == self.username\n\n    @property\n    def author(self):\n        username = self.username\n\n        if not username:\n            return {}\n\n        authorinfo = self.membership_tool.getMemberInfo(username)\n        portrait = self.membership_tool.getPersonalPortrait(username)\n\n        if not authorinfo or not portrait:\n            return {}\n\n        return {\n            'info': authorinfo,\n            'portrait': portrait\n        }\n\n    @property\n    def member_info(self):\n        current_member = self.portal_state.member()\n        if not current_member or not current_member.getId():\n            return {'url': None, 'email': None}\n\n        return {\n            'url': quote_plus(current_member.getId()),\n            'email': current_member.getProperty('email')\n        }\n\n    @property\n    def author_content(self):\n        results = []\n\n        plone_view = self.context.restrictedTraverse(\n            '@@plone'\n        )\n\n        brains = self.portal_catalog.searchResults(\n            Creator=self.username,\n            sort_on='created',\n            sort_order='reverse'\n        )\n\n        for brain in brains[:10]:\n            results.append({\n                'title': pretty_title_or_id(\n                    self, brain\n                ),\n                'date': plone_view.toLocalizedTime(\n                    brain.Date\n                ),\n                'url': brain.getURL()\n            })\n\n        return results\n\n    def home_folder(self, username):\n        return self.membership_tool.getHomeFolder(id=username)\n\n    def __call__(self):\n\n        self.portal_properties = getUtility(\n            IPropertiesTool\n        )\n\n        self.portal_catalog = getToolByName(\n            self.context, 'portal_catalog'\n        )\n\n        # XXX: getUtility call does not work.\n        self.membership_tool = getToolByName(\n            self.context, 'portal_membership'\n        )\n\n        self.portal_state = getMultiAdapter(\n            (self.context, self.request),\n            name=u'plone_portal_state'\n        )\n\n        self.feedback_form = AuthorFeedbackForm(\n            self.context, self.request\n        )\n        self.feedback_form.update()\n        self.feedback_form.widgets[\"author\"].mode = HIDDEN_MODE\n        self.feedback_form.widgets[\"referer\"].mode = HIDDEN_MODE\n        self.feedback_form.widgets[\"author\"].value = self.username\n        self.feedback_form.widgets[\"referer\"].value = self.request.get(\n            'referer',\n            self.request.get('HTTP_REFERER', 'unknown url')\n        )\n\n        registry = getUtility(IRegistry)\n        security_settings = registry.forInterface(\n            ISecuritySchema, prefix='plone')\n        allow_anonymous_view_about = security_settings.allow_anon_views_about\n\n        mail_settings = registry.forInterface(IMailSchema, prefix='plone')\n        self.email_from_address = mail_settings.email_from_address\n\n        if self.is_anonymous and not allow_anonymous_view_about:\n            raise Unauthorized()\n\n        return self.index()\n", "path": "Products/CMFPlone/browser/author.py"}]}