Why Drupal can not create a temporary file? - drupal

I cloned a repository from my drupal site to a local environment running MAMP PRO in a windows machine. all the files and data base are setup correctly. when I try to run Drupal 8 I get this error. I know its a permissions problem but I'm not sure where to change the permissions or what to do. I tried many settings and I get same results.
Drupal\Core\File\Exception\FileWriteException: Temporary file 'temporary://filF92B.tmp' could not be created. in Drupal\Core\File\FileSystem->saveData() (line 521 of core\lib\Drupal\Core\File\FileSystem.php).
Drupal\google_tag\Entity\ContainerManager->saveSnippets(Object) (Line: 77)
Drupal\google_tag\Entity\ContainerManager->createAssets(Object) (Line: 160)
Drupal\google_tag\Entity\ContainerManager->getScriptAttachments(Array) (Line: 70)
google_tag_page_attachments(Array) (Line: 297)
Drupal\Core\Render\MainContent\HtmlRenderer->invokePageAttachmentHooks(Array) (Line: 273)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 117)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object) (Line: 156)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 708)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

Ok, It looks like is not necessary to access the admin panel to change the temporary directory. In settings.php I was able to modify the below line to set it up. After clearing Drupal cache and adding an .htaccess file it worked.
$settings['file_temp_path'] = '/tmp';

I was having this problem while working with the copy of a site in production in local with XAMPP.
I solved it adding this to settings.php:
$settings["file_temp_path"] = sys_get_temp_dir();

Go to Administrator -> Configuration -> Media -> File System (/admin/config/media/file-system) to get your temporary path. Make sure it have the right privileges for the Apache user.

Related

Having problem while overriding admin custom content type edit form

I am facing a very strange problem while trying to override a custom content type edit form template in my custom theme.
I have a custom theme mysite_admin (sub-theme of seven) with a minimal setup. It has mandatory mysite_admin.info.yml and mysite_admin.theme file. I created a content type named Very Basic Content Type for demonstration purposes. Now I want to preprocess the edit form for said content type so I create a following function in mysite_admin.theme file
function mysite_admin_preprocess_form__node_very_basic_content_type_form(&$variables) {
ksm($variables);
}
flush cashes, and instead of seeing the variables output on top of my edit form I see an exception as follows
The website encountered an unexpected error. Please try again later.
TypeError: Argument 1 passed to Drupal\Core\Render\Element::setAttributes() must be of the type array, null given, called in /home/ejaz/sites/mysite/core/includes/form.inc on line 362 in Drupal\Core\Render\Element::setAttributes() (line 173 of core/lib/Drupal/Core/Render/Element.php).
Drupal\Core\Render\Element::setAttributes() (Line: 362)
template_preprocess_form() (Line: 287)
Drupal\Core\Theme\ThemeManager->render() (Line: 431)
Drupal\Core\Render\Renderer->doRender() (Line: 200)
Drupal\Core\Render\Renderer->render() (Line: 226)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext() (Line: 227)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare() (Line: 117)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse() (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray()
call_user_func() (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch() (Line: 156)
Symfony\Component\HttpKernel\HttpKernel->handleRaw() (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle() (Line: 57)
Drupal\Core\StackMiddleware\Session->handle() (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle() (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass() (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle() (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() (Line: 23)
Stack\StackedHttpKernel->handle() (Line: 694)
Drupal\Core\DrupalKernel->handle() (Line: 19)
I see the same exception if I create a template named form--node-very-basic-content-type-form.html.twig in my custom theme's templates directory while not having said preprocess function in theme file.
Wagwan?
Use hook_form_alter instead and play with it by adding condition specific to your content edit form.

Airflow: RBAC with flask, werkzeug.routing.BuildError

I am trying to configure RBAC (setting a webserver_config.py of Flask-AppBuilder) with AUTH_LDAP, and after successfully logging through LDAP, I am getting the following error:
File "/usr/local/lib/python3.6/site-packages/airflow/www_rbac/templates/appbuilder/navbar_menu.html", line 47, in top-level template code
<li>{{ menu_item(item2) }}</li>
File "/usr/local/lib/python3.6/site-packages/jinja2/runtime.py", line 574, in _invoke
rv = self._func(*arguments)
File "/usr/local/lib/python3.6/site-packages/airflow/www_rbac/templates/appbuilder/navbar_menu.html", line 21, in template
<a tabindex="-1" href="{{item.get_url()}}">
File "/usr/local/lib/python3.6/site-packages/flask_appbuilder/menu.py", line 24, in get_url
return url_for(f"{self.baseview.endpoint}.{self.baseview.default_view}")
File "/usr/local/lib/python3.6/site-packages/flask/helpers.py", line 370, in url_for
return appctx.app.handle_url_build_error(error, endpoint, values)
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2215, in handle_url_build_error
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/flask/helpers.py", line 358, in url_for
endpoint, values, method=method, force_external=external
File "/usr/local/lib/python3.6/site-packages/werkzeug/routing.py", line 2020, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.BuildError: Could not build url for endpoint 'BaseView.list'. Did you mean 'DagModelView.list' instead?
I am using airflow 1.10.9 with werkzeug==0.16.0.
Do you have any hints, please?
Thank you in advance.
I understood the problem and fixed the problem.
It was related to the RBAC activation (in airflow) and a previous plugin of mines, which hadn't default_view = "index" defined in Plugin's view.

Graphite Error with MapSeries

I get this error with every parameter combination I try for "mapSeries"
Using Graphite v0.9.15
Example url -
http://myGraphite/render/?width=586&height=308&target=mapSeries(server.server1.route.root.admin.%2A.invocation_count,5)&from=-6h&until=now&format=json
Another one -
http://myGraphite/render/?width=586&height=308&target=mapSeries(server.%2A.route.root.admin.%2A.invocation_count,1)&from=-6h&until=now&format=json
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/django/core/handlers/base.py", line 109, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "/opt/graphite/webapp/graphite/render/views.py", line 125, in renderView
seriesList = evaluateTarget(requestContext, target)
File "/opt/graphite/webapp/graphite/render/evaluator.py", line 10, in evaluateTarget
result = evaluateTokens(requestContext, tokens)
File "/opt/graphite/webapp/graphite/render/evaluator.py", line 21, in evaluateTokens
return evaluateTokens(requestContext, tokens.expression)
File "/opt/graphite/webapp/graphite/render/evaluator.py", line 27, in evaluateTokens
func = SeriesFunctions[tokens.call.func]
KeyError: u'mapSeries'
I've found that "mapSeries" is not available in the 0.9.x branch.
It is in the 0.10.x branch.

Autoit Unable to open the script file [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am creating a basic installer in autoit. After compiling the script, I got the error Unable to open the script file when trying to run it.
The Script:
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=..\Resources\unnamed.ico
#AutoIt3Wrapper_Outfile=..\..\..\Desktop\Minecraft Server Launcher Installer.exe
#AutoIt3Wrapper_UseX64=n
#AutoIt3Wrapper_Res_File_Add=C:\Users\Kristian\SkyDrive\Autoit\Bungee Minecraft Server Launcher.exe, rt_rcdata, Launcher
#AutoIt3Wrapper_Res_File_Add=C:\Users\Kristian\SkyDrive\Autoit\Bungee Server Launcher\Licence.txt, rt_rcdata, Licence
#AutoIt3Wrapper_Add_Constants=n
#AutoIt3Wrapper_AU3Check_Stop_OnWarning=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <resources.au3>
$msgbox1 = MsgBox(36, "Minecraft Server Launcher Installer", "Do you want to install the Launcher?")
If $msgbox1 = 6 Then
GUICreate("Minecraft Server Launcher Installer", 373, 325)
GUICtrlCreateLabel("Read the following agreement. Scroll down to view the rest of the agreement.", 10, 10)
GUICtrlCreateEdit(_ResourceGetAsString("Licence"), 10, 51, 350, 191, $WS_VSCROLL + $ES_READONLY + $ES_MULTILINE)
GUICtrlCreateLabel("Do you accept all the terms of the license agreement? Selecting No" & #CRLF & "cancels the installation. You must accept the agreement to install.", 10, 250)
$YES = GUICtrlCreateButton("Yes", 204, 296, 75, 23)
$NO = GUICtrlCreateButton("No", 290, 296, 75, 23)
GUISetState(#SW_SHOW)
While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
Exit
Case $YES
Choose_Loc()
Case $NO
Exit
EndSwitch
WEnd
EndIf
Func Choose_Loc()
GUIDelete()
GUICreate("Minecraft Server Launcher Installer", 363, 108)
GUICtrlCreateLabel("Choose Install Location", 10, 5)
$INPUT = GUICtrlCreateInput("C:\Program Files (x86)\KnarCraft\Minecraft Server Launcher", 10, 40, 255, 22)
$BROWSE = GUICtrlCreateButton("Browse...", 275, 40, 80, 23)
$CANCEL = GUICtrlCreateButton("Cancel", 275, 75, 80, 23)
$OK = GUICtrlCreateButton("OK", 185, 75, 80, 23)
GUISetState(#SW_SHOW)
While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
Exit
Case $CANCEL
Exit
Case $OK
Install($INPUT)
Case $BROWSE
$FOLDER = FileSelectFolder("Choose Install Location...", "", 7)
If Not $FOLDER = "" Then GUICtrlSetData($INPUT, $FOLDER)
EndSwitch
WEnd
EndFunc ;==>Choose_Loc
Func Install($INPUT)
_ResourceSaveToFile(GUICtrlRead($INPUT) & "\Bungee Minecraft Server Launcher.exe", "Launcher", $RT_RCDATA, 0, 1)
FileCreateShortcut(GUICtrlRead($INPUT) & "\Bungee Minecraft Server Launcher.exe", #DesktopDir & "\Bungee Minecraft Server Launcher.ink")
GUIDelete()
If Not #error Then
MsgBox(36, "Finished", "Installation completed with no errors. Please enjoy your new software.")
Else
MsgBox(16, "Finished", "The installation was interrupted by an error and the software may not work.")
EndIf
Exit
EndFunc ;==>Install
I know that it's this line that creates the error:
#AutoIt3Wrapper_Res_File_Add=C:\Users\Kristian\SkyDrive\Autoit\Bungee Server Launcher\Licence.txt, rt_rcdata, Licence
But I don't know why or how to fix it. I had the same problem with:
#AutoIt3Wrapper_Res_File_Add=C:\Users\Kristian\SkyDrive\Autoit\Bungee Minecraft Server Launcher.exe, rt_rcdata, Launcher
I know that it's the Res_Add line because if I remove that line, the error will disappear.
I stopped using the res file stuff, and switched to FileInstall() :
FileInstall("C:\Users\Kristian\SkyDrive\Autoit\Bungee Minecraft Server Launcher.exe",#TEMPDIR & "\Bungee Minecraft Server Launcher.exe")
FileInstall("C:\Users\Kristian\SkyDrive\Autoit\Bungee Server Launcher\Licence.txt",#TEMPDIR & "\Licence.txt")
Then you just use the file. Also, your paths are different:
Autoit\{BUNGEE MINECRAFT SERVER LAUNCHER.EXE}
Autoit\Bungee Server Launcher\{LICENCE.TXT}
Open up a command prompt and check the full path :
cd C:\Users\Kristian\SkyDrive\Autoit & dir licence.txt /b /s
Another solution would be to make the text file a variable. Open the file in SciTE, replace the regular expression ^(.*)$ by "$1" & #CRLF &_, then copy and paste it into the script.
Here is the code with FileInstall() and a couple fixes. I tested with different paths, and it worked. Functions should be self-contained, so I made them mostly internal. Ideally, you'd have them do a Return SetError() and put the MsgBox() outside the function call.
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=..\Resources\unnamed.ico
#AutoIt3Wrapper_Outfile=..\..\..\Desktop\Minecraft Server Launcher Installer.exe
#AutoIt3Wrapper_UseX64=n
#AutoIt3Wrapper_Add_Constants=n
#AutoIt3Wrapper_AU3Check_Stop_OnWarning=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
; Target path of temp files - you should add code to delete these when done
$LAUNCHPATH = #TempDir & "\BMSLauncher.exe"
$LICENCEPATH = #TempDir & "\BMSLicence.txt"
; Check if the install files exist, and if not, output to console
$EXIST1 = FileExists("C:\Users\Kristian\SkyDrive\Autoit\Bungee Minecraft Server Launcher.exe")
$EXIST2 = FileExists("C:\Users\Kristian\SkyDrive\Autoit\Bungee Server Launcher\Licence.txt")
If Not $EXIST1 Or Not $EXIST2 Then
ConsoleWrite("ERROR! FILE(S) NOT FOUND!" & #CRLF)
If Not $EXIST1 Then ConsoleWrite("LAUNCHER FILE NOT FOUND!" & #CRLF)
If Not $EXIST2 Then ConsoleWrite("LICENCE FILE NOT FOUND!" & #CRLF)
EndIf
; Copy files to destination
FileInstall("C:\Users\Kristian\SkyDrive\Autoit\Bungee Minecraft Server Launcher.exe", $LAUNCHPATH, 1)
FileInstall("C:\Users\Kristian\SkyDrive\Autoit\Bungee Server Launcher\Licence.txt", $LICENCEPATH, 1)
; Read licence file to variable
$LICENCE = FileRead($LICENCEPATH)
$msgbox1 = MsgBox(36, "Minecraft Server Launcher Installer", "Do you want to install the Launcher?")
If $msgbox1 = 6 Then
$EULAGUI = GUICreate("Minecraft Server Launcher Installer", 373, 325)
GUICtrlCreateLabel("Read the following agreement. Scroll down to view the rest of the agreement.", 10, 10)
GUICtrlCreateEdit($LICENCE, 10, 51, 350, 191, $WS_VSCROLL + $ES_READONLY + $ES_MULTILINE)
GUICtrlCreateLabel("Do you accept all the terms of the license agreement? Selecting No" & #CRLF & "cancels the installation. You must accept the agreement to install.", 10, 250)
$YES = GUICtrlCreateButton("Yes", 204, 296, 75, 23)
$NO = GUICtrlCreateButton("No", 290, 296, 75, 23)
GUISetState(#SW_SHOW)
While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE, $NO
Exit
Case $YES
GUIDelete($EULAGUI)
Choose_Loc()
EndSwitch
WEnd
EndIf
Func Choose_Loc()
Local $LOCGUI = GUICreate("Minecraft Server Launcher Installer", 363, 108)
GUICtrlCreateLabel("Choose Install Location", 10, 5)
$INPUT = GUICtrlCreateInput("C:\Program Files (x86)\KnarCraft\Minecraft Server Launcher", 10, 40, 255, 22)
$BROWSE = GUICtrlCreateButton("Browse...", 275, 40, 80, 23)
$CANCEL = GUICtrlCreateButton("Cancel", 275, 75, 80, 23)
$OK = GUICtrlCreateButton("OK", 185, 75, 80, 23)
GUISetState(#SW_SHOW)
While 1
; you could make the switch guigetmsg() without $msg, idk what's best practice here
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE, $CANCEL
Exit
Case $OK
Local $INSTALLPATH = GUICtrlRead($INPUT)
If FileExists($INSTALLPATH) Then
GUIDelete($LOCGUI)
Install($LAUNCHPATH, $INSTALLPATH)
EndIf
Case $BROWSE
$FOLDER = FileSelectFolder("Choose Install Location...", "", 7)
If Not $FOLDER = "" Then GUICtrlSetData($INPUT, $FOLDER)
EndSwitch
WEnd
EndFunc ;==>Choose_Loc
Func Install($FPATH, $IPATH)
Local $ERROR
; you should check for a trailing slash on the $IPATH input
$IPATH &= "\Bungee Minecraft Server Launcher.exe"
FileCopy($FPATH, $IPATH)
$ERROR = #error
FileCreateShortcut($IPATH, #DesktopDir & "\Bungee Minecraft Server Launcher.ink")
If Not #error And Not $ERROR Then
MsgBox(64, "Finished", "Installation completed with no errors. Please enjoy your new software.")
Else
MsgBox(16, "Finished", "The installation was interrupted by an error and the software may not work.")
EndIf
Exit
EndFunc ;==>Install
Make sure the file is in the same dir as the script and Try:
#AutoIt3Wrapper_Res_File_Add=Licence.txt, rt_rcdata, Licence
If you still have problems, try to turn off UPX.

How to clean up old interfaces on zc.relation catalog?

I was using plone.directives.form version 1.0 with Plone 4.2.5 and after upgrading to 4.2.6 I started seeing the following traceback and I guess its due to plone.directives.form being upgraded to version 1.1.
How can I avoid this error? The only line of code that is not from default Plone on the traceback is on der.freitag.handlers where it does a transaction.commit() and the content type is just a regular dexterity content type.
1385740390.020.496977141203 http://10.100.0.207:8081/website/front-page/atomkraft/++add++der.freitag.customizablearticlelink
Traceback (innermost last):
Module ZPublisher.Publish, line 138, in publish
Module ZPublisher.mapply, line 77, in mapply
Module ZPublisher.Publish, line 48, in call_object
Module plone.z3cform.layout, line 70, in __call__
Module plone.z3cform.layout, line 54, in update
Module plone.dexterity.browser.add, line 112, in update
Module plone.z3cform.fieldsets.extensible, line 59, in update
Module plone.z3cform.patch, line 30, in GroupForm_update
Module z3c.form.group, line 138, in update
Module z3c.form.action, line 99, in execute
Module z3c.form.button, line 315, in __call__
Module z3c.form.button, line 170, in __call__
Module plone.dexterity.browser.add, line 99, in handleAdd
Module z3c.form.form, line 247, in createAndAdd
Module plone.dexterity.browser.add, line 78, in add
Module plone.dexterity.utils, line 152, in addContentToContainer
Module Products.BTreeFolder2.BTreeFolder2, line 455, in _setObject
Module zope.event, line 31, in notify
Module zope.component.event, line 24, in dispatch
Module zope.component._api, line 136, in subscribers
Module zope.component.registry, line 321, in subscribers
Module zope.interface.adapter, line 585, in subscribers
Module zope.component.event, line 32, in objectEventNotify
Module zope.component._api, line 136, in subscribers
Module zope.component.registry, line 321, in subscribers
Module zope.interface.adapter, line 585, in subscribers
Module der.freitag.handlers, line 126, in set_customizable_article_link_id
Module transaction._manager, line 89, in commit
Module transaction._transaction, line 329, in commit
Module transaction._transaction, line 443, in _commitResources
Module ZODB.Connection, line 567, in commit
Module ZODB.Connection, line 623, in _commit
Module ZODB.Connection, line 658, in _store_objects
Module ZODB.serialize, line 422, in serialize
Module ZODB.serialize, line 431, in _dump
PicklingError: Can't pickle <class 'plone.directives.form.schema.Schema'>: attribute lookup plone.directives.form.schema.Schema failed
EDIT: the object that is being created has a relation field (a z3c.relationfield.schema.RelationChoice) and it turns out that zc.relation keeps a list of all interfaces provided by each member of any relation. Thus, after upgrading from plone.directives.form version 1.0 to version 1.1 the interfaces on plone.directives.form can no longer be resolved.
From z3c.relationfield documentation I don't see any option to update relations, so the only solution would be to get all relations and recreate them?
Just for reference that's how I fixed it:
While still on plone.directives.form 1.0 update your objects so that they do no longer provide the plone.directives.form.schema.Schema interface.
Then re-create the relations:
from z3c.relationfield import RelationValue
from zc.relation.interfaces import ICatalog
from zope.app.intid.interfaces import IIntIds
from zope.component import getUtility
from zope.event import notify
from zope.lifecycleevent import ObjectModifiedEvent
logger = logging.getLogger(LOGGER)
relations_catalog = getUtility(ICatalog)
intids = getUtility(IIntIds)
relations = [rel for rel in relations_catalog.findRelations()]
len_relations = len(relations)
logger.info('Relations needed to update: {0}'.format(len_relations))
for relation in relations:
# get the object link and the object linked
object_with_link = relation.from_object
object_linked_to = relation.to_object
# remove the broken relation
object_with_link.reference = None
# let the catalog remove the old relation
notify(ObjectModifiedEvent(object_with_link))
# create a new relation
object_linked_to_intid = intids.getId(object_linked_to)
new_relation = RelationValue(object_linked_to_intid)
object_with_link.reference = new_relation
# let the catalog know about this new relation
notify(ObjectModifiedEvent(object_with_link))
After this, stop the instance, run buildout again to update plone.directives.form to version 1.1 and voilĂ !
The Schema class is now in plone.supermodel.model, not plone.directives.form.schema.
However, the real problem you should try to fix is that the code is for some reason trying to store a schema in the ZODB. Pickling/unpickling Zope interfaces is not supported.
In case someone runs into this type of problem and cannot bring the old package back, here's another approach:
import transaction
from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.User import system
from Testing.makerequest import makerequest
from zope.component.hooks import setSite
from zope.globalrequest import setRequest
from zc.relation.interfaces import ICatalog
from z3c.relationfield.event import _relations
from z3c.relationfield.event import _setRelation
from zope.component import getUtility
app = makerequest(app)
newSecurityManager(None, system)
portal = app.Plone
setSite(portal)
portal.REQUEST['PARENTS'] = [portal]
portal.REQUEST.setVirtualRoot('/')
setRequest(portal.REQUEST)
THRESHOLD = 100
relations_catalog = getUtility(ICatalog)
paths = ['/'.join(r.from_object.getPhysicalPath())
for r in relations_catalog.findRelations() if r.from_object]
relations_catalog.clear()
counter = 0
for path in paths:
obj = app.unrestrictedTraverse(path)
for name, relation in _relations(obj):
_setRelation(obj, name, relation)
counter += 1
if counter % THRESHOLD == 0:
transaction.savepoint()
transaction.commit()
One more option, I developed a package called collective.diversion that is designed to ease the pain of pickling errors when moving a class. Neither of the above scripts worked for me, however using collective.diversion did.
Adding the package to the buildout and including the following ZCML caused the items to be loaded, and they'll be persisted back in the correct place on write, so reindexing the catalogue should be sufficient.
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:diversion="http://namespaces.plone.org/diversion">
<diversion:class
old="plone.directives.form.schema.Schema"
new="plone.supermodel.model.Schema"
/>
</configure>

Resources