Commit 9b2ca2d2 authored by Hanno Schlichting's avatar Hanno Schlichting

ZClasses have been deprecated for two major releases. They have been removed...

ZClasses have been deprecated for two major releases. They have been removed in this version of Zope.
parent b68d0206
...@@ -9,6 +9,9 @@ Zope Changes ...@@ -9,6 +9,9 @@ Zope Changes
Restructuring Restructuring
- ZClasses have been deprecated for two major releases. They have been
removed in this version of Zope.
- Avoid deprecation warnings for the md5 and sha modules in Python 2.6 - Avoid deprecation warnings for the md5 and sha modules in Python 2.6
by adding conditional imports for the hashlib module. by adding conditional imports for the hashlib module.
......
...@@ -2,7 +2,7 @@ Zope Help System ...@@ -2,7 +2,7 @@ Zope Help System
The Zope Help System provides context-sensitive on-line help for The Zope Help System provides context-sensitive on-line help for
Zope users. The system is flexible and can provide help for Zope users. The system is flexible and can provide help for
Python and ZClass-based Zope Products. Python Zope Products.
In the future the Help System will be expanded to provide additional In the future the Help System will be expanded to provide additional
help including API documentation. help including API documentation.
...@@ -31,22 +31,6 @@ Architecture ...@@ -31,22 +31,6 @@ Architecture
object which has methods for drawing help buttons. This object lives object which has methods for drawing help buttons. This object lives
in the Zope application object and has an id of 'HelpSys'. in the Zope application object and has an id of 'HelpSys'.
Writing Help for ZClasses
Suppose you've created an addable type of object with ZClasses.
You'd like the management screens of your objects to have help
buttons just like the standard Zope management screens.
First create some Help Topics though the web which document your
management screens. Do this by going to your ZClass's Product and
creating new Help Topics inside the Product Help object.
Next go to your ZClass and click on the 'Views' management tab. On
this screen you define your object's management views. Each view has
a name, a method, and optionally a help topic. If you select a help
topic for a view, a help button will be drawn on that management
view and it will be linked to the help topic you select.
Writing Help for Python Products Writing Help for Python Products
To support help your Python product needs to register help topics To support help your Python product needs to register help topics
......
...@@ -91,25 +91,6 @@ class RoleManager: ...@@ -91,25 +91,6 @@ class RoleManager:
REQUEST, REQUEST,
manage_tabs_message='The permission mapping has been updated') manage_tabs_message='The permission mapping has been updated')
def _isBeingUsedAsAMethod(self, REQUEST =None, wannaBe=0):
try:
if hasattr(self, 'aq_self'):
r=self.aq_acquire('_isBeingUsedAsAMethod_')
else:
r=self._isBeingUsedAsAMethod_
except: r=0
if REQUEST is not None:
if not r != (not wannaBe): REQUEST.response.notFoundError()
return r
def _isBeingAccessedAsZClassDefinedInstanceMethod(self):
p=getattr(self,'__parent__',None)
if p is None: return 0 # Not wrapped
base=getattr(p, 'aq_base', None)
return type(base) is PermissionMapper
InitializeClass(RoleManager) InitializeClass(RoleManager)
......
...@@ -49,7 +49,6 @@ ftp_access='FTP access' ...@@ -49,7 +49,6 @@ ftp_access='FTP access'
import_export_objects='Import/Export objects' import_export_objects='Import/Export objects'
join_leave_versions='Join/leave Versions' join_leave_versions='Join/leave Versions'
manage_vocabulary='Manage Vocabulary' manage_vocabulary='Manage Vocabulary'
manage_zclasses='Manage Z Classes'
manage_zcatalog_entries='Manage ZCatalog Entries' manage_zcatalog_entries='Manage ZCatalog Entries'
manage_zcatalog_indexes='Manage ZCatalogIndex Entries' manage_zcatalog_indexes='Manage ZCatalogIndex Entries'
manage_properties='Manage properties' manage_properties='Manage properties'
......
...@@ -17,9 +17,7 @@ $Id$ ...@@ -17,9 +17,7 @@ $Id$
from cgi import escape from cgi import escape
from Acquisition import Acquired from Acquisition import Acquired
from Acquisition import aq_get
from Acquisition import aq_base from Acquisition import aq_base
from Acquisition import Implicit
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.Permissions import change_permissions from AccessControl.Permissions import change_permissions
...@@ -36,12 +34,6 @@ from AccessControl.requestmethod import requestmethod ...@@ -36,12 +34,6 @@ from AccessControl.requestmethod import requestmethod
DEFAULTMAXLISTUSERS=250 DEFAULTMAXLISTUSERS=250
def _isBeingUsedAsAMethod(self):
return aq_get(self, '_isBeingUsedAsAMethod_', 0)
def _isNotBeingUsedAsAMethod(self):
return not aq_get(self, '_isBeingUsedAsAMethod_', 0)
class RoleManager(Base, RoleManager): class RoleManager(Base, RoleManager):
...@@ -54,11 +46,6 @@ class RoleManager(Base, RoleManager): ...@@ -54,11 +46,6 @@ class RoleManager(Base, RoleManager):
manage_options=( manage_options=(
{'label':'Security', 'action':'manage_access', {'label':'Security', 'action':'manage_access',
'help':('OFSP','Security.stx'), 'help':('OFSP','Security.stx'),
'filter': _isNotBeingUsedAsAMethod,
},
{'label':'Define Permissions', 'action':'manage_access',
'help':('OFSP','Security_Define-Permissions.stx'),
'filter': _isBeingUsedAsAMethod,
}, },
) )
...@@ -137,7 +124,6 @@ class RoleManager(Base, RoleManager): ...@@ -137,7 +124,6 @@ class RoleManager(Base, RoleManager):
def manage_role(self, role_to_manage, permissions=[], REQUEST=None): def manage_role(self, role_to_manage, permissions=[], REQUEST=None):
"""Change the permissions given to the given role. """Change the permissions given to the given role.
""" """
self._isBeingUsedAsAMethod(REQUEST, 0)
for p in self.ac_inherited_permissions(1): for p in self.ac_inherited_permissions(1):
name, value = p[:2] name, value = p[:2]
p=Permission(name,value,self) p=Permission(name,value,self)
...@@ -156,7 +142,6 @@ class RoleManager(Base, RoleManager): ...@@ -156,7 +142,6 @@ class RoleManager(Base, RoleManager):
def manage_acquiredPermissions(self, permissions=[], REQUEST=None): def manage_acquiredPermissions(self, permissions=[], REQUEST=None):
"""Change the permissions that acquire. """Change the permissions that acquire.
""" """
self._isBeingUsedAsAMethod(REQUEST, 0)
for p in self.ac_inherited_permissions(1): for p in self.ac_inherited_permissions(1):
name, value = p[:2] name, value = p[:2]
p=Permission(name,value,self) p=Permission(name,value,self)
...@@ -243,7 +228,6 @@ class RoleManager(Base, RoleManager): ...@@ -243,7 +228,6 @@ class RoleManager(Base, RoleManager):
are acquired, in addition to the ones specified, otherwise the are acquired, in addition to the ones specified, otherwise the
permissions are restricted to only the designated roles. permissions are restricted to only the designated roles.
""" """
self._isBeingUsedAsAMethod(REQUEST, 0)
for p in self.ac_inherited_permissions(1): for p in self.ac_inherited_permissions(1):
name, value = p[:2] name, value = p[:2]
if name==permission_to_manage: if name==permission_to_manage:
...@@ -259,18 +243,12 @@ class RoleManager(Base, RoleManager): ...@@ -259,18 +243,12 @@ class RoleManager(Base, RoleManager):
escape(permission_to_manage)) escape(permission_to_manage))
_normal_manage_access=DTMLFile('dtml/access', globals()) _normal_manage_access=DTMLFile('dtml/access', globals())
_method_manage_access=DTMLFile('dtml/methodAccess', globals())
manage_reportUserPermissions=DTMLFile('dtml/reportUserPermissions', globals()) manage_reportUserPermissions=DTMLFile('dtml/reportUserPermissions', globals())
security.declareProtected(change_permissions, 'manage_access') security.declareProtected(change_permissions, 'manage_access')
def manage_access(self, REQUEST, **kw): def manage_access(self, REQUEST, **kw):
"""Return an interface for making permissions settings. """Return an interface for making permissions settings.
""" """
if hasattr(self, '_isBeingUsedAsAMethod') and \
self._isBeingUsedAsAMethod():
return apply(self._method_manage_access,(), kw)
else:
return apply(self._normal_manage_access,(), kw) return apply(self._normal_manage_access,(), kw)
security.declareProtected(change_permissions, 'manage_changePermissions') security.declareProtected(change_permissions, 'manage_changePermissions')
...@@ -278,7 +256,6 @@ class RoleManager(Base, RoleManager): ...@@ -278,7 +256,6 @@ class RoleManager(Base, RoleManager):
def manage_changePermissions(self, REQUEST): def manage_changePermissions(self, REQUEST):
"""Change all permissions settings, called by management screen. """Change all permissions settings, called by management screen.
""" """
self._isBeingUsedAsAMethod(REQUEST, 0)
valid_roles=self.valid_roles() valid_roles=self.valid_roles()
indexes=range(len(valid_roles)) indexes=range(len(valid_roles))
have=REQUEST.has_key have=REQUEST.has_key
......
...@@ -6,14 +6,12 @@ ...@@ -6,14 +6,12 @@
<p class="form-help"> <p class="form-help">
This interface is used to define how the operations of this object This interface is used to define how the operations of this object
correspond to the operations defined by your product or ZClass. correspond to the operations defined by your product.
</p> </p>
<p class="form-help"> <p class="form-help">
The first column below lists the permissions for this object. The second The first column below lists the permissions for this object. The second
specifies the permissions that should have this permission in this product specifies the permissions that should have this permission in this product.
or ZClass. For ZClass methods, only permissions that are defined for the
ZClass are permitted.
</p> </p>
<p class="form-help"> <p class="form-help">
......
...@@ -44,13 +44,6 @@ class RestrictiveObject(Implicit): ...@@ -44,13 +44,6 @@ class RestrictiveObject(Implicit):
class PermissiveObject(Explicit): class PermissiveObject(Explicit):
_Edit_Things__Permission = ['Anonymous'] _Edit_Things__Permission = ['Anonymous']
class ZClassMethodish(Implicit):
# Think of this as a method that should only be visible to users
# who have the edit permission.
_View_Permission = '_Edit_Things__Permission'
_Edit_Things__Permission = ''
_Delete_Permission = ''
def assertPRoles(ob, permission, expect): def assertPRoles(ob, permission, expect):
""" """
...@@ -118,15 +111,6 @@ class PermissionRoleTests (unittest.TestCase): ...@@ -118,15 +111,6 @@ class PermissionRoleTests (unittest.TestCase):
assertPRoles(o, EditThingsPermission, ('Manager','Owner',)) assertPRoles(o, EditThingsPermission, ('Manager','Owner',))
assertPRoles(o, DeletePermission, ('Manager',)) assertPRoles(o, DeletePermission, ('Manager',))
def testPermissionMapping(self):
app = AppRoot()
app.c = ImplicitContainer()
app.c.o = ZClassMethodish()
o = app.c.o
assertPRoles(o, ViewPermission, ('Manager','Owner',))
assertPRoles(o, EditThingsPermission, ())
assertPRoles(o, DeletePermission, ())
def testPermissionRoleSupportsGetattr(self): def testPermissionRoleSupportsGetattr(self):
a = PermissionRole('a') a = PermissionRole('a')
self.failUnless(getattr(a, '__roles__') == ('Manager',)) self.failUnless(getattr(a, '__roles__') == ('Manager',))
......
...@@ -103,12 +103,6 @@ def is_acquired(ob, hasattr=hasattr, aq_base=aq_base, absattr=absattr): ...@@ -103,12 +103,6 @@ def is_acquired(ob, hasattr=hasattr, aq_base=aq_base, absattr=absattr):
except KeyError: except KeyError:
pass pass
if hasattr(parent,'_objects'):
# XXX This is really icky
# This ugly mess is for ZClass methods I think
if absId+' ' in parent.objectIds():
return 0
if hasattr(aq_base(ob), 'isTopLevelPrincipiaApplicationObject') and \ if hasattr(aq_base(ob), 'isTopLevelPrincipiaApplicationObject') and \
ob.isTopLevelPrincipiaApplicationObject: ob.isTopLevelPrincipiaApplicationObject:
# This object the top level # This object the top level
......
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
__doc__='''Factory objects
$Id$'''
__version__='$Revision: 1.27 $'[11:-2]
from AccessControl.Permissions import edit_factories
from AccessControl.Permissions import use_factories
from AccessControl.Role import RoleManager
from AccessControl.SecurityInfo import ClassSecurityInfo
from Acquisition import Acquired
from Acquisition import Implicit
from App.class_init import InitializeClass
from App.special_dtml import DTMLFile
from Persistence import Persistent
from OFS.SimpleItem import Item
class Factory(RoleManager,
Persistent,
Implicit,
Item
):
"""Model factory meta-data
"""
meta_type = 'Zope Factory'
icon = 'p_/Factory_icon'
security = ClassSecurityInfo()
security.declareObjectProtected(use_factories)
permission = '' # Waaaa
_setObject=_getOb = Acquired
manage_options = (
(
{'label':'Edit', 'action':'manage_main',
'help':('OFSP','Zope-Factory_Edit.stx')},
)
+ RoleManager.manage_options
+ Item.manage_options
)
def __init__(self, id, title, object_type, initial, permission=''):
self.id=id
self.title=title
self.object_type=object_type
self.initial=initial
self.permission=permission
security.declarePrivate('initializePermission')
def initializePermission(self):
self.manage_setPermissionMapping((use_factories,),
(self.permission,))
security.declareProtected(edit_factories, 'manage_edit')
def manage_edit(self, title, object_type, initial, permission='',
REQUEST=None):
"Modify factory properties."
self._unregister()
self.title = title
self.object_type = object_type
self.initial = initial
self.permission = permission
self.manage_setPermissionMapping((use_factories,), (permission,))
self._register()
if REQUEST is not None:
return self.manage_main(self, REQUEST)
def manage_afterAdd(self, item, container):
from App.Product import Product # local to avoid circular import
if hasattr(self, 'aq_parent'):
container=self.aq_parent
elif item is not self:
container=None
if (item is self or
getattr(container, '__class__', None) is Product):
self._register()
def manage_beforeDelete(self, item, container):
from App.Product import Product # local to avoid circular import
if hasattr(self, 'aq_parent'):
container=self.aq_parent
elif item is not self:
container=None
if (item is self or
getattr(container, '__class__', None) is Product):
self._unregister()
def _register(self):
# Register with the product folder
product =self.aq_parent
product.aq_acquire('_manage_add_product_meta_type')(
product, self.id, self.object_type, self.permission)
def _unregister(self):
# Unregister with the product folder
product = self.aq_parent
product.aq_acquire('_manage_remove_product_meta_type')(
product, self.id, self.object_type)
security.declareProtected(edit_factories, 'manage_main')
manage_main = DTMLFile('dtml/editFactory',globals())
security.declareProtected(use_factories, 'index_html')
def index_html(self, REQUEST):
""" Main factory view
"""
return getattr(self, self.initial)(self.aq_parent, REQUEST)
def objectIds(self):
return filter(
lambda id, myid=self.id: id != myid,
self.aq_parent.objectIds()
)
InitializeClass(Factory)
class ProductFactory(Factory): pass
...@@ -139,25 +139,6 @@ class Tabs(Base): ...@@ -139,25 +139,6 @@ class Tabs(Base):
out.append(last) out.append(last)
return '/'.join(out) return '/'.join(out)
security.declarePublic('class_manage_path')
def class_manage_path(self):
if self.__class__.__module__[:1] != '*':
return
path = getattr(self.__class__, '_v_manage_path_roles', None)
if path is None:
meta_type = self.meta_type
for zclass in self.getPhysicalRoot()._getProductRegistryData(
'zclasses'):
if zclass['meta_type'] == meta_type:
break
else:
self.__class__._v_manage_path_roles = ''
return
path = self.__class__._v_manage_path_roles = (
'%(product)s/%(id)s' % zclass)
if path:
return '/Control_Panel/Products/%s/manage_workspace' % path
InitializeClass(Tabs) InitializeClass(Tabs)
......
...@@ -34,38 +34,22 @@ ...@@ -34,38 +34,22 @@
# on restart if there is still a product directory. # on restart if there is still a product directory.
from cgi import escape
import cPickle import cPickle
import marshal
import os import os
import re import re
from urllib import quote
import zlib import zlib
import transaction import transaction
from AccessControl.Owned import UnownableOwner from AccessControl.Owned import UnownableOwner
from AccessControl.Permissions import manage_zclasses
from AccessControl.SecurityInfo import ClassSecurityInfo from AccessControl.SecurityInfo import ClassSecurityInfo
from AccessControl.unauthorized import Unauthorized from AccessControl.unauthorized import Unauthorized
from App.class_init import InitializeClass from App.class_init import InitializeClass
from App.special_dtml import DTMLFile from App.special_dtml import DTMLFile
from OFS.Folder import Folder from OFS.Folder import Folder
from App.Factory import Factory
from App.Permission import PermissionManager from App.Permission import PermissionManager
# BBB: ZClasses are deprecated but we don't want the warning to appear here
import warnings
warnings.filterwarnings('ignore', message='^ZClasses', append=1)
try:
import ZClasses
finally:
del warnings.filters[-1]
try:
del __warningregistry__
except NameError:
pass
class ProductFolder(Folder): class ProductFolder(Folder):
"Manage a collection of Products" "Manage a collection of Products"
...@@ -75,25 +59,12 @@ class ProductFolder(Folder): ...@@ -75,25 +59,12 @@ class ProductFolder(Folder):
meta_type = 'Product Management' meta_type = 'Product Management'
icon = 'p_/ProductFolder_icon' icon = 'p_/ProductFolder_icon'
all_meta_types={'name': 'Product', 'action': 'manage_addProductForm',
'permission': manage_zclasses},
meta_types = all_meta_types
# This prevents subobjects from being owned! # This prevents subobjects from being owned!
_owner = UnownableOwner _owner = UnownableOwner
def _product(self, name): def _product(self, name):
return getattr(self, name) return getattr(self, name)
manage_addProductForm = DTMLFile('dtml/addProduct', globals())
def manage_addProduct(self, id, title, REQUEST=None):
""" Create a product.
"""
i=Product(id, title)
self._setObject(id,i)
if REQUEST is not None:
return self.manage_main(self,REQUEST,update_menu=1)
def _canCopy(self, op=0): def _canCopy(self, op=0):
return 0 return 0
...@@ -111,7 +82,6 @@ class Product(Folder, PermissionManager): ...@@ -111,7 +82,6 @@ class Product(Folder, PermissionManager):
version='' version=''
configurable_objects_=() configurable_objects_=()
import_error_=None import_error_=None
_isBeingUsedAsAMethod_=1
def new_version(self, def new_version(self,
_intending=re.compile(r"[0-9]+").search, #TS _intending=re.compile(r"[0-9]+").search, #TS
...@@ -135,21 +105,9 @@ class Product(Folder, PermissionManager): ...@@ -135,21 +105,9 @@ class Product(Folder, PermissionManager):
meta_types=( meta_types=(
ZClasses.meta_types + PermissionManager.meta_types
PermissionManager.meta_types +
(
{
'name': Factory.meta_type,
'action': 'manage_addPrincipiaFactoryForm'
},
)
) )
manage_addZClassForm=ZClasses.methods['manage_addZClassForm']
manage_addZClass =ZClasses.methods['manage_addZClass']
manage_subclassableClassNames=ZClasses.methods[
'manage_subclassableClassNames']
manage_options = ( manage_options = (
(Folder.manage_options[0],) + (Folder.manage_options[0],) +
tuple(Folder.manage_options[2:]) tuple(Folder.manage_options[2:])
...@@ -161,18 +119,6 @@ class Product(Folder, PermissionManager): ...@@ -161,18 +119,6 @@ class Product(Folder, PermissionManager):
_reserved_names=('Help',) _reserved_names=('Help',)
manage_addPrincipiaFactoryForm = DTMLFile('dtml/addFactory', globals())
def manage_addPrincipiaFactory(
self, id, title, object_type, initial, permission=None, REQUEST=None):
""" Add a ZClass factory
"""
i = Factory(id, title, object_type, initial, permission)
self._setObject(id,i)
factory = self._getOb(id)
factory.initializePermission()
if REQUEST is not None:
return self.manage_main(self,REQUEST,update_menu=1)
def __init__(self, id, title): def __init__(self, id, title):
self.id=id self.id=id
self.title=title self.title=title
...@@ -200,9 +146,6 @@ class Product(Folder, PermissionManager): ...@@ -200,9 +146,6 @@ class Product(Folder, PermissionManager):
def permissionMappingPossibleValues(self): def permissionMappingPossibleValues(self):
return self.possible_permissions() return self.possible_permissions()
def zclass_product_name(self):
return self.id
def getProductHelp(self): def getProductHelp(self):
"""Returns the ProductHelp object associated with the Product. """Returns the ProductHelp object associated with the Product.
""" """
...@@ -239,63 +182,6 @@ class Product(Folder, PermissionManager): ...@@ -239,63 +182,6 @@ class Product(Folder, PermissionManager):
pass pass
return refresh_txt return refresh_txt
def manage_refresh(self, REQUEST, manage_tabs_message=None):
"""Displays the refresh management screen.
"""
import Globals # for data
from App.RefreshFuncs import getLastRefreshException
from App.RefreshFuncs import isAutoRefreshEnabled
from App.RefreshFuncs import getDependentProducts
from App.RefreshFuncs import listRefreshableModules
from App.RefreshFuncs import listAutoRefreshableModules
error_type = error_value = error_tb = None
exc = getLastRefreshException(self.id)
if exc is not None:
error_type, error_value, error_tb = exc
exc = None
refresh_txt = self._readRefreshTxt()
# Read the persistent refresh information.
auto = isAutoRefreshEnabled(self._p_jar, self.id)
deps = getDependentProducts(self._p_jar, self.id)
# List all product modules.
mods = listRefreshableModules(self.id)
loaded_modules = []
prefix = 'Products.%s' % self.id
prefixdot = prefix + '.'
lpdot = len(prefixdot)
for name, module in mods:
if name == prefix or name[:lpdot] == prefixdot:
name = name[lpdot:]
if not name:
name = '__init__'
loaded_modules.append(name)
all_auto = listAutoRefreshableProducts(self._p_jar)
for pid in all_auto:
# Ignore products that don't have a refresh.txt.
if self._readRefreshTxt(pid) is None:
all_auto.remove(pid)
auto_other = filter(lambda productId, myId=self.id:
productId != myId, all_auto)
# Return rendered DTML.
return self._refresh_dtml(REQUEST,
id=self.id,
refresh_txt=refresh_txt,
error_type=error_type,
error_value=error_value,
error_tb=error_tb,
devel_mode=Globals.DevelopmentMode,
auto_refresh_enabled=auto,
auto_refresh_other=auto_other,
dependent_products=deps,
loaded_modules=loaded_modules,
manage_tabs_message=manage_tabs_message,
management_view='Refresh')
def manage_performRefresh(self, REQUEST=None): def manage_performRefresh(self, REQUEST=None):
""" Attempts to perform a refresh operation. """ Attempts to perform a refresh operation.
""" """
...@@ -484,8 +370,6 @@ def initializeProduct(productp, name, home, app): ...@@ -484,8 +370,6 @@ def initializeProduct(productp, name, home, app):
transaction.abort() transaction.abort()
return product return product
# Give the ZClass fixup code in Application
Globals.__disk_product_installed__ = 1
return product return product
def ihasattr(o, name): def ihasattr(o, name):
......
...@@ -28,7 +28,6 @@ from App.Product import doInstall ...@@ -28,7 +28,6 @@ from App.Product import doInstall
from DateTime.DateTime import DateTime from DateTime.DateTime import DateTime
from HelpSys import APIHelpTopic from HelpSys import APIHelpTopic
from HelpSys import HelpTopic from HelpSys import HelpTopic
from HelpSys.HelpSys import ProductHelp
from OFS.misc_ import Misc_ from OFS.misc_ import Misc_
from OFS.misc_ import misc_ from OFS.misc_ import misc_
from OFS.ObjectManager import ObjectManager from OFS.ObjectManager import ObjectManager
...@@ -36,7 +35,6 @@ from OFS.ObjectManager import ObjectManager ...@@ -36,7 +35,6 @@ from OFS.ObjectManager import ObjectManager
from zope.interface import implementedBy from zope.interface import implementedBy
from App.FactoryDispatcher import FactoryDispatcher from App.FactoryDispatcher import FactoryDispatcher
import ZClasses # to enable 'PC.registerBaseClass()'
# Waaaa # Waaaa
import Products import Products
...@@ -229,41 +227,6 @@ class ProductContext: ...@@ -229,41 +227,6 @@ class ProductContext:
setattr(misc_, pid, Misc_(pid, {})) setattr(misc_, pid, Misc_(pid, {}))
getattr(misc_, pid)[name]=icon getattr(misc_, pid)[name]=icon
def registerZClass(self, Z, meta_type=None):
#
# Convenience method, now deprecated -- clients should
# call 'ZClasses.createZClassForBase()' themselves at
# module import time, passing 'globals()', so that the
# ZClass will be available immediately.
#
base_class=Z._zclass_
if meta_type is None:
if hasattr(base_class, 'meta_type'): meta_type=base_class.meta_type
else: meta_type=base_class.__name__
module=base_class.__module__
name=base_class.__name__
key="%s/%s" % (module, name)
if module[:9]=='Products.': module=module.split('.')[1]
else: module=module.split('.')[0]
info="%s: %s" % (module, name)
Products.meta_class_info[key]=info # meta_type
Products.meta_classes[key]=Z
def registerBaseClass(self, base_class, meta_type=None):
#
# Convenience method, now deprecated -- clients should
# call 'ZClasses.createZClassForBase()' themselves at
# module import time, passing 'globals()', so that the
# ZClass will be available immediately.
#
Z = ZClasses.createZClassForBase( base_class, self.__pack )
return Z
def getProductHelp(self): def getProductHelp(self):
""" """
Returns the ProductHelp associated with the current Product. Returns the ProductHelp associated with the current Product.
......
...@@ -136,10 +136,7 @@ class ProductRegistryMixin: ...@@ -136,10 +136,7 @@ class ProductRegistryMixin:
def _manage_remove_product_data(self, type, product, id): def _manage_remove_product_data(self, type, product, id):
values=filter( values=filter(
lambda d, product=product, id=id: lambda d, product=product, id=id:
not (d['product'] in not (d['product']==product and d['id']==id),
(product,
'methods' # hack to get around inner ZClass reg. bug
) and d['id']==id),
self.aq_maybe('_getProductRegistryData')(type) self.aq_maybe('_getProductRegistryData')(type)
) )
...@@ -160,9 +157,6 @@ class ProductRegistry(ProductRegistryMixin): ...@@ -160,9 +157,6 @@ class ProductRegistry(ProductRegistryMixin):
_product_permissions=() _product_permissions=()
_product_ac_permissions=() _product_ac_permissions=()
_product_zclasses=() # product, id, meta_type, class
def _getProductRegistryMetaTypes(self): return self._product_meta_types def _getProductRegistryMetaTypes(self): return self._product_meta_types
def _setProductRegistryMetaTypes(self, v): self._product_meta_types=v def _setProductRegistryMetaTypes(self, v): self._product_meta_types=v
......
<dtml-var manage_page_header>
<dtml-var "manage_form_title(this(), _,
form_title='Add Object Factory',
help_product='OFSP',
help_topic='Zope-Factory_Add.stx'
)">
<p class="form-help">
A Factory allows you to place entries in the Zope Product add list. In the
form below the <em>add list name</em> is the name under which your entry will
appear in the Zope Product add list. The <em>method</em> is the method that
will be invoked when a user adds a new object. This must be one of the
objects in the product, typically a Python Script or DTML object.
</p>
<dtml-if objectIds>
<form action="manage_addPrincipiaFactory" method="post">
<table cellspacing="0" cellpadding="2" border="0">
<tr>
<td align="left" valign="top">
<div class="form-label">
Id
</div>
</td>
<td align="left" valign="top">
<input type="text" name="id" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-optional">
Title
</div>
</td>
<td align="left" valign="top">
<input type="text" name="title" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Add list name
</div>
</td>
<td align="left" valign="top">
<input type="text" name="object_type" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Method
</div>
</td>
<td align="left" valign="top">
<div class="form-element">
<select name="initial">
<dtml-in objectItems>
<dtml-if "meta_type != 'Principia Factory'">
<option>&dtml-sequence-key;</option>
</dtml-if>
</dtml-in>
</select>
</div>
</td>
</tr>
<tr>
<td></td>
<td align="left" valign="top">
<div class="form-element">
<br />
<input type="submit" name="submit" value="Generate" />
</div>
</td>
</tr>
</table>
</form>
<dtml-else>
<p class="form-help">
Before you can define a factory, you have to define one or more "methods",
such as Document or other objects that do the factory's work.
</p>
</dtml-if>
<dtml-var manage_page_footer>
<dtml-var manage_page_header>
<dtml-var "manage_form_title(this(), _,
form_title='Add Product',
help_product='OFSP',
help_topic='Product_Add.stx'
)">
<p class="form-help">
Products allows you to define new types of Zope objects. A Product contains
other objects including a Factory which allows you to make your Product
objects available via the Product add list.
</p>
<form action="manage_addProduct" method="POST">
<table cellspacing="0" cellpadding="2" border="0">
<tr>
<td align="left" valign="top">
<div class="form-label">
Id
</div>
</td>
<td align="left" valign="top">
<input type="text" name="id" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-optional">
Title
</div>
</td>
<td align="left" valign="top">
<input type="text" name="title" size="40" />
</td>
</tr>
<tr>
<td></td>
<td align="left" valign="top">
<div class="form-element">
<br />
<input type="submit" name="submit" value="Generate" />
</div>
</td>
</tr>
</table>
</form>
<dtml-var manage_page_footer>
...@@ -113,12 +113,7 @@ ...@@ -113,12 +113,7 @@
</dtml-if> </dtml-if>
<strong> <strong>
<dtml-if meta_type> <dtml-if meta_type>
<dtml-if class_manage_path>
<a href="&dtml-BASEPATH1;&dtml-class_manage_path;"
title="Manage the ZClass of this object">&dtml-meta_type;</a>
<dtml-else>
&dtml-meta_type; &dtml-meta_type;
</dtml-if>
<dtml-else> <dtml-else>
Object Object
</dtml-if> </dtml-if>
......
...@@ -86,8 +86,6 @@ ...@@ -86,8 +86,6 @@
'checked' or ' '"> 'checked' or ' '">
<input type="checkbox" name="selections:list" <input type="checkbox" name="selections:list"
value="&dtml-sequence-item;" &dtml-checked; /> value="&dtml-sequence-item;" &dtml-checked; />
<a href="../&dtml-sequence-item;/manage_refresh"
>&dtml-sequence-item;</a><br />
</dtml-let> </dtml-let>
</dtml-in> </dtml-in>
<input type="submit" name="manage_selectDependentProducts:method" <input type="submit" name="manage_selectDependentProducts:method"
......
...@@ -124,11 +124,9 @@ class ObjectRef(HelpBase): ...@@ -124,11 +124,9 @@ class ObjectRef(HelpBase):
if is_class(v) and hasattr(v, 'meta_type') and \ if is_class(v) and hasattr(v, 'meta_type') and \
hasattr(v, '__ac_permissions__'): hasattr(v, '__ac_permissions__'):
if callable(v.meta_type): if callable(v.meta_type):
try: meta_type=v.meta_type() meta_type=v.meta_type()
except: else:
# Ack. probably a ZClass :( meta_type=v.meta_type
meta_type=None
else: meta_type=v.meta_type
if (meta_type is not None) and (meta_type not in hidden): if (meta_type is not None) and (meta_type not in hidden):
dict[meta_type]=ObjectItem(k, v) dict[meta_type]=ObjectItem(k, v)
if is_module(v) and hasattr(v, '__path__'): if is_module(v) and hasattr(v, '__path__'):
......
...@@ -66,7 +66,6 @@ class Application(ApplicationDefaultPermissions, ...@@ -66,7 +66,6 @@ class Application(ApplicationDefaultPermissions,
__defined_roles__ = ('Manager','Anonymous','Owner') __defined_roles__ = ('Manager','Anonymous','Owner')
web__form__method = 'GET' web__form__method = 'GET'
isTopLevelPrincipiaApplicationObject = 1 isTopLevelPrincipiaApplicationObject = 1
_isBeingUsedAsAMethod_ = 0
# Create the help system object # Create the help system object
HelpSys = HelpSys('HelpSys') HelpSys = HelpSys('HelpSys')
...@@ -213,77 +212,6 @@ class Application(ApplicationDefaultPermissions, ...@@ -213,77 +212,6 @@ class Application(ApplicationDefaultPermissions,
# We're at the base of the path. # We're at the base of the path.
return ('',) return ('',)
security.declarePrivate('fixupZClassDependencies')
def fixupZClassDependencies(self, rebuild=0):
# Note that callers should not catch exceptions from this method
# to ensure that the transaction gets aborted if the registry
# cannot be rebuilt for some reason. Returns true if any ZClasses
# were registered as a result of the call or the registry was
# rebuilt.
jar=self._p_jar
result=0
if rebuild:
from BTrees.OOBTree import OOBTree
jar.root()['ZGlobals'] = OOBTree()
result = 1
zglobals =jar.root()['ZGlobals']
reg_has_key=zglobals.has_key
products=self.Control_Panel.Products
for product in products.objectValues():
items=list(product.objectItems())
finished_dict={}
finished = finished_dict.has_key
while items:
name, ob = items.pop()
base=aq_base(ob)
if finished(id(base)):
continue
finished_dict[id(base)] = None
try:
# Try to re-register ZClasses if they need it.
if hasattr(base,'_register') and hasattr(base,'_zclass_'):
class_id=getattr(base._zclass_, '__module__', None)
if class_id and not reg_has_key(class_id):
ob._register()
result=1
if not rebuild:
LOG.info('Registered ZClass: %s' % ob.id)
# Include subobjects.
if hasattr(base, 'objectItems'):
m = list(ob.objectItems())
items.extend(m)
# Try to find ZClasses-in-ZClasses.
if hasattr(base, 'propertysheets'):
ps = ob.propertysheets
if (hasattr(ps, 'methods') and
hasattr(ps.methods, 'objectItems')):
m = list(ps.methods.objectItems())
items.extend(m)
except:
LOG.warn('Broken objects exist in product %s.' % product.id,
exc_info=sys.exc_info())
return result
security.declarePrivate('checkGlobalRegistry')
def checkGlobalRegistry(self):
"""Check the global (zclass) registry for problems, which can
be caused by things like disk-based products being deleted.
Return true if a problem is found"""
try:
keys=list(self._p_jar.root()['ZGlobals'].keys())
except:
LOG.error(
'A problem was found when checking the global product '\
'registry. This is probably due to a Product being '\
'uninstalled or renamed. The traceback follows.',
exc_info=sys.exc_info())
return 1
return 0
security.declarePrivate('_setInitializerFlag') security.declarePrivate('_setInitializerFlag')
def _setInitializerFlag(self, flag): def _setInitializerFlag(self, flag):
if self._initializer_registry is None: if self._initializer_registry is None:
...@@ -346,13 +274,11 @@ class AppInitializer: ...@@ -346,13 +274,11 @@ class AppInitializer:
self.install_session_data_manager() self.install_session_data_manager()
self.install_browser_id_manager() self.install_browser_id_manager()
self.install_required_roles() self.install_required_roles()
self.install_zglobals()
self.install_inituser() self.install_inituser()
self.install_errorlog() self.install_errorlog()
self.install_products() self.install_products()
self.install_standards() self.install_standards()
self.install_virtual_hosting() self.install_virtual_hosting()
self.check_zglobals()
def install_cp_and_products(self): def install_cp_and_products(self):
app = self.getApp() app = self.getApp()
...@@ -507,16 +433,6 @@ class AppInitializer: ...@@ -507,16 +433,6 @@ class AppInitializer:
app.__ac_roles__=app.__ac_roles__ + ('Authenticated',) app.__ac_roles__=app.__ac_roles__ + ('Authenticated',)
self.commit('Added Authenticated role') self.commit('Added Authenticated role')
def install_zglobals(self):
app = self.getApp()
# Make sure we have ZGlobals
root=app._p_jar.root()
if not root.has_key('ZGlobals'):
from BTrees.OOBTree import OOBTree
root['ZGlobals'] = OOBTree()
self.commit('Added ZGlobals')
def install_inituser(self): def install_inituser(self):
app = self.getApp() app = self.getApp()
...@@ -559,61 +475,6 @@ class AppInitializer: ...@@ -559,61 +475,6 @@ class AppInitializer:
app._setInitializerFlag('virtual_hosting') app._setInitializerFlag('virtual_hosting')
self.commit('Added virtual_hosting') self.commit('Added virtual_hosting')
def check_zglobals(self):
import Globals
if not doInstall():
return
app = self.getApp()
# Check for dangling pointers (broken zclass dependencies) in the
# global class registry. If found, rebuild the registry. Note that
# if the check finds problems but fails to successfully rebuild the
# registry we abort the transaction so that we don't leave it in an
# indeterminate state.
did_fixups=0
bad_things=0
try:
if app.checkGlobalRegistry():
LOG.info(
'Beginning attempt to rebuild the global ZClass registry.')
app.fixupZClassDependencies(rebuild=1)
did_fixups=1
LOG.info(
'The global ZClass registry has successfully been rebuilt.')
transaction.get().note('Rebuilt global product registry')
transaction.commit()
except:
bad_things=1
LOG.error('The attempt to rebuild the registry failed.',
exc_info=True)
transaction.abort()
# Now we need to see if any (disk-based) products were installed
# during intialization. If so (and the registry has no errors),
# there may still be zclasses dependent on a base class in the
# newly installed product that were previously broken and need to
# be fixed up. If any really Bad Things happened (dangling pointers
# were found in the registry but it couldn't be rebuilt), we don't
# try to do anything to avoid making the problem worse.
if (not did_fixups) and (not bad_things):
# App.Product.initializeProduct will set this if a disk-based
# product was added or updated and we are not a ZEO client.
if getattr(Globals, '__disk_product_installed__', None):
try:
LOG.info('New disk product detected, determining if we need '
'to fix up any ZClasses.')
if app.fixupZClassDependencies():
LOG.info('Repaired broken ZClass dependencies.')
self.commit('Repaired broked ZClass dependencies')
except:
LOG.error('Attempt to fixup ZClass dependencies after '
'detecting an updated disk-based product failed.',
exc_info=sys.exc_info())
transaction.abort()
def install_products(self): def install_products(self):
app = self.getApp() app = self.getApp()
# this defers to a function for b/c reasons # this defers to a function for b/c reasons
......
...@@ -19,7 +19,6 @@ import sys ...@@ -19,7 +19,6 @@ import sys
import time import time
from AccessControl.Permissions import view_management_screens from AccessControl.Permissions import view_management_screens
from AccessControl.Role import _isBeingUsedAsAMethod
from AccessControl.SecurityInfo import ClassSecurityInfo from AccessControl.SecurityInfo import ClassSecurityInfo
from AccessControl.SecurityManagement import getSecurityManager from AccessControl.SecurityManagement import getSecurityManager
from AccessControl.unauthorized import Unauthorized from AccessControl.unauthorized import Unauthorized
...@@ -48,11 +47,6 @@ def managersExist(ob): ...@@ -48,11 +47,6 @@ def managersExist(ob):
return 0 return 0
def filterCacheTab(ob): def filterCacheTab(ob):
if _isBeingUsedAsAMethod(ob):
# Show tab when in a ZClass def that uses Cacheable as a base.
parent = aq_parent(aq_inner(ob))
return isCacheable(parent)
else:
return managersExist(ob) return managersExist(ob)
def filterCacheManagers(orig, container, name, value, extra): def filterCacheManagers(orig, container, name, value, extra):
...@@ -150,34 +144,12 @@ class Cacheable: ...@@ -150,34 +144,12 @@ class Cacheable:
''' '''
return self.__enabled and self.ZCacheable_getCache() return self.__enabled and self.ZCacheable_getCache()
security.declareProtected(ViewManagementScreensPermission,
'ZCacheable_isAMethod')
def ZCacheable_isAMethod(self):
'''
Returns 1 when this object is a ZClass method.
'''
m = _isBeingUsedAsAMethod(self)
return m
security.declarePrivate('ZCacheable_getObAndView') security.declarePrivate('ZCacheable_getObAndView')
def ZCacheable_getObAndView(self, view_name): def ZCacheable_getObAndView(self, view_name):
""" """
If this object is a method of a ZClass and we're working Returns self and view_name unchanged.
with the primary view, uses the ZClass instance as ob
and our own ID as the view_name. Otherwise returns
self and view_name unchanged.
""" """
ob = self return self, view_name
if not view_name and self.ZCacheable_isAMethod():
# This is a ZClass method.
ob = aq_parent(aq_inner(self))
if isCacheable(ob):
view_name = self.getId()
else:
# Both the parent and the child have to be
# cacheable.
ob = self
return ob, view_name
security.declarePrivate('ZCacheable_get') security.declarePrivate('ZCacheable_get')
def ZCacheable_get(self, view_name='', keywords=None, def ZCacheable_get(self, view_name='', keywords=None,
...@@ -253,8 +225,6 @@ class Cacheable: ...@@ -253,8 +225,6 @@ class Cacheable:
# mtime_func # mtime_func
# self.mtime # self.mtime
# self.__class__.mtime # self.__class__.mtime
# (if in a ZClass) zclass_instance.mtime
# zclass_instance.__class__.mtime
mtime = 0 mtime = 0
if mtime_func: if mtime_func:
# Allow mtime_func to influence the mod time. # Allow mtime_func to influence the mod time.
...@@ -264,14 +234,6 @@ class Cacheable: ...@@ -264,14 +234,6 @@ class Cacheable:
klass = getattr(base, '__class__', None) klass = getattr(base, '__class__', None)
if klass: if klass:
mtime = max(getattr(klass, '_p_mtime', mtime), mtime) mtime = max(getattr(klass, '_p_mtime', mtime), mtime)
if self.ZCacheable_isAMethod():
# This is a ZClass method.
instance = aq_parent(aq_inner(self))
base = aq_base(instance)
mtime = max(getattr(base, '_p_mtime', mtime), mtime)
klass = getattr(base, '__class__', None)
if klass:
mtime = max(getattr(klass, '_p_mtime', mtime), mtime)
return mtime return mtime
security.declareProtected(ViewManagementScreensPermission, security.declareProtected(ViewManagementScreensPermission,
...@@ -340,8 +302,7 @@ class Cacheable: ...@@ -340,8 +302,7 @@ class Cacheable:
security.declareProtected(ChangeCacheSettingsPermission, security.declareProtected(ChangeCacheSettingsPermission,
'ZCacheable_setEnabled') 'ZCacheable_setEnabled')
def ZCacheable_setEnabled(self, enabled=0, REQUEST=None): def ZCacheable_setEnabled(self, enabled=0, REQUEST=None):
'''Changes the enabled flag. Normally used only when '''Changes the enabled flag.'''
setting up cacheable ZClass methods.'''
self.__enabled = enabled and 1 or 0 self.__enabled = enabled and 1 or 0
if REQUEST is not None: if REQUEST is not None:
return self.ZCacheable_manage( return self.ZCacheable_manage(
......
...@@ -99,10 +99,6 @@ class FindSupport(Base): ...@@ -99,10 +99,6 @@ class FindSupport(Base):
if hasattr(base, 'objectItems'): if hasattr(base, 'objectItems'):
try: items=obj.objectItems() try: items=obj.objectItems()
except: return result except: return result
else:
if getattr(base, 'meta_type', None) == 'Z Class':
try: items=obj.propertysheets.methods.objectItems()
except: return result
else: else:
return result return result
...@@ -145,12 +141,7 @@ class FindSupport(Base): ...@@ -145,12 +141,7 @@ class FindSupport(Base):
add_result((p, ob)) add_result((p, ob))
dflag=0 dflag=0
is_zclass = getattr(bs, 'meta_type', None) == 'Z Class' if search_sub and (hasattr(bs, 'objectItems')):
if search_sub and (hasattr(bs, 'objectItems') or is_zclass):
if is_zclass:
subob = ob.propertysheets.methods
sub_p = '%s/propertysheets/methods' % p
else:
subob = ob subob = ob
sub_p = p sub_p = p
self.ZopeFind(subob, obj_ids, obj_metatypes, self.ZopeFind(subob, obj_ids, obj_metatypes,
......
...@@ -290,8 +290,6 @@ class PropertySheet(Traversable, Persistent, Implicit): ...@@ -290,8 +290,6 @@ class PropertySheet(Traversable, Persistent, Implicit):
def _propertyMap(self): def _propertyMap(self):
# Return a tuple of mappings, giving meta-data for properties. # Return a tuple of mappings, giving meta-data for properties.
# Some ZClass instances dont seem to have an _properties, so
# we have to fake it...
return self.p_self()._properties return self.p_self()._properties
security.declareProtected(access_contents_information, 'propertyMap') security.declareProtected(access_contents_information, 'propertyMap')
...@@ -769,43 +767,6 @@ class DefaultPropertySheets(PropertySheets): ...@@ -769,43 +767,6 @@ class DefaultPropertySheets(PropertySheets):
InitializeClass(DefaultPropertySheets) InitializeClass(DefaultPropertySheets)
class FixedSchema(PropertySheet):
"""A Fixed-schema property sheet has no control over it's schema
It gets its schema from another proprtysheet but has control over
its value storage.
This mix-in is used for ZClass instance proprtysheets, which store
their data in instances, but get their schema from the
proprtysheet managed in the ZClass.
"""
def __init__(self, id, base, md=None):
FixedSchema.inheritedAttribute('__init__')(self, id, md)
self._base=base
def _propertyMap(self):
# Return a tuple of mappings, giving meta-data for properties.
r = []
for d in self._base._propertyMap():
d = d.copy()
mode = d.get('mode', 'wd')
if 'd' in mode:
d['mode']=filter(lambda c: c != 'd', mode)
r.append(d)
return tuple(r)
def propertyMap(self):
return self._propertyMap()
def property_extensible_schema__(self):
return 0
return self._base._extensible
InitializeClass(FixedSchema)
class vps(Base): class vps(Base):
"""Virtual Propertysheets """Virtual Propertysheets
......
...@@ -2,18 +2,7 @@ ...@@ -2,18 +2,7 @@
<dtml-var manage_tabs> <dtml-var manage_tabs>
<form action="&dtml-absolute_url;" method="POST"> <form action="&dtml-absolute_url;" method="POST">
<dtml-if ZCacheable_isAMethod>
<input type="checkbox" name="enable" value="1"<dtml-if
ZCacheable_enabled> checked="checked"</dtml-if
>><span class="form-label">Cache this view of the object</span>
<br>
<div class="form-element">
<input class="form-element" type="submit" name="ZCacheable_setEnabled:method"
value="Save Changes">
</div>
<dtml-else>
<div class="form-element"> <div class="form-element">
<span class="form-label"> <span class="form-label">
Cache this object using: Cache this object using:
...@@ -44,8 +33,6 @@ Cache this object using: ...@@ -44,8 +33,6 @@ Cache this object using:
</div> </div>
</dtml-if> </dtml-if>
</dtml-if>
<dtml-var ZCacheable_configHTML> <dtml-var ZCacheable_configHTML>
</form> </form>
......
...@@ -321,10 +321,6 @@ class IManageable(Interface): ...@@ -321,10 +321,6 @@ class IManageable(Interface):
""" """
""" """
def class_manage_path():
"""
"""
# XXX: might contain non-API methods and outdated comments; # XXX: might contain non-API methods and outdated comments;
# not synced with ZopeBook API Reference; # not synced with ZopeBook API Reference;
...@@ -890,15 +886,6 @@ class IApplication(IFolder, IContainmentRoot): ...@@ -890,15 +886,6 @@ class IApplication(IFolder, IContainmentRoot):
""" """
""" """
def fixupZClassDependencies(rebuild=0):
"""
"""
def checkGlobalRegistry():
"""Check the global (zclass) registry for problems, which can
be caused by things like disk-based products being deleted.
Return true if a problem is found"""
################################################## ##################################################
# Event interfaces # Event interfaces
......
...@@ -52,7 +52,6 @@ class p_: ...@@ -52,7 +52,6 @@ class p_:
InstalledProduct_icon=ImageFile('App/www/installedProduct.gif') InstalledProduct_icon=ImageFile('App/www/installedProduct.gif')
BrokenProduct_icon=ImageFile('App/www/brokenProduct.gif') BrokenProduct_icon=ImageFile('App/www/brokenProduct.gif')
Product_icon=ImageFile('App/www/product.gif') Product_icon=ImageFile('App/www/product.gif')
Factory_icon=ImageFile('App/www/factory.gif')
Permission_icon=ImageFile('App/www/permission.gif') Permission_icon=ImageFile('App/www/permission.gif')
ProductFolder_icon=ImageFile('App/www/productFolder.gif') ProductFolder_icon=ImageFile('App/www/productFolder.gif')
PyPoweredSmall_Gif=ImageFile('App/www/PythonPoweredSmall.gif') PyPoweredSmall_Gif=ImageFile('App/www/PythonPoweredSmall.gif')
...@@ -62,8 +61,7 @@ class p_: ...@@ -62,8 +61,7 @@ class p_:
zopelogo_jpg=ImageFile('App/www/zopelogo.jpg') zopelogo_jpg=ImageFile('App/www/zopelogo.jpg')
Properties_icon=ImageFile('OFS/www/Properties_icon.gif') Properties_icon=ImageFile('OFS/www/Properties_icon.gif')
Methods_icon=ImageFile('ZClasses/methods.gif') Propertysheets_icon=ImageFile('OFS/www/Properties_icon.gif')
Propertysheets_icon=ImageFile('ZClasses/propertysheets.gif')
ProductHelp_icon=ImageFile('HelpSys/images/productHelp.gif') ProductHelp_icon=ImageFile('HelpSys/images/productHelp.gif')
HelpTopic_icon=ImageFile('HelpSys/images/helpTopic.gif') HelpTopic_icon=ImageFile('HelpSys/images/helpTopic.gif')
......
...@@ -176,15 +176,6 @@ class TestInitialization( unittest.TestCase ): ...@@ -176,15 +176,6 @@ class TestInitialization( unittest.TestCase ):
self.failUnless('Owner' in app.__ac_roles__) self.failUnless('Owner' in app.__ac_roles__)
self.failUnless('Authenticated' in app.__ac_roles__) self.failUnless('Authenticated' in app.__ac_roles__)
def test_install_zglobals(self):
from BTrees.OOBTree import OOBTree
self.configure(good_cfg)
i = self.getOne()
i.install_zglobals()
root = i.getApp()._p_jar.root()
self.failUnless(root.has_key('ZGlobals'))
self.failUnless(isinstance(root['ZGlobals'], OOBTree))
def test_install_inituser(self): def test_install_inituser(self):
fname = os.path.join(TEMPNAME, 'inituser') fname = os.path.join(TEMPNAME, 'inituser')
f = open(fname, 'w') f = open(fname, 'w')
......
...@@ -25,8 +25,3 @@ def initialize(context): ...@@ -25,8 +25,3 @@ def initialize(context):
BTreeFolder2.manage_addBTreeFolder), BTreeFolder2.manage_addBTreeFolder),
icon='btreefolder2.gif', icon='btreefolder2.gif',
) )
#context.registerHelp()
#context.registerHelpTitle('Zope Help')
context.registerBaseClass(BTreeFolder2.BTreeFolder2)
...@@ -6,8 +6,6 @@ ...@@ -6,8 +6,6 @@
<five:deprecatedManageAddDelete <five:deprecatedManageAddDelete
class="AccessControl.User.BasicUserFolder"/> class="AccessControl.User.BasicUserFolder"/>
<five:deprecatedManageAddDelete
class="App.Factory.Factory"/>
<five:deprecatedManageAddDelete <five:deprecatedManageAddDelete
class="App.Permission.Permission"/> class="App.Permission.Permission"/>
...@@ -43,9 +41,4 @@ ...@@ -43,9 +41,4 @@
<five:deprecatedManageAddDelete <five:deprecatedManageAddDelete
class="Products.ZCatalog.CatalogPathAwareness.CatalogAware"/> class="Products.ZCatalog.CatalogPathAwareness.CatalogAware"/>
<five:deprecatedManageAddDelete
class="ZClasses.Property.ZCommonSheet"/>
<five:deprecatedManageAddDelete
class="ZClasses.ZClass.ZClass"/>
</configure> </configure>
...@@ -17,29 +17,11 @@ __version__='$Revision: 1.38 $'[11:-2] ...@@ -17,29 +17,11 @@ __version__='$Revision: 1.38 $'[11:-2]
import Version, OFS.Image, OFS.Folder, AccessControl.User import Version, OFS.Image, OFS.Folder, AccessControl.User
import OFS.DTMLMethod, OFS.DTMLDocument, OFS.PropertySheets import OFS.DTMLMethod, OFS.DTMLDocument, OFS.PropertySheets
import OFS.OrderedFolder import OFS.OrderedFolder
import ZClasses.ObjectManager
from AccessControl.Permissions import add_documents_images_and_files from AccessControl.Permissions import add_documents_images_and_files
from AccessControl.Permissions import add_folders from AccessControl.Permissions import add_folders
from ZClasses import createZClassForBase
from App.ImageFile import ImageFile from App.ImageFile import ImageFile
createZClassForBase( OFS.DTMLMethod.DTMLMethod, globals()
, 'ZDTMLMethod', 'DTML Method' )
createZClassForBase( OFS.DTMLDocument.DTMLDocument, globals()
, 'ZDTMLDocument', 'DTML Document' )
createZClassForBase( OFS.Image.Image, globals()
, 'ZImage', 'Image' )
createZClassForBase( OFS.Image.File, globals()
, 'ZFile', 'File' )
createZClassForBase( OFS.Folder.Folder, globals()
, 'ZFolder', 'Folder' )
createZClassForBase( OFS.OrderedFolder.OrderedFolder, globals() )
createZClassForBase( AccessControl.User.UserFolder, globals()
, 'ZUserFolder', 'User Folder' )
createZClassForBase( AccessControl.User.User, globals()
, 'ZUser', 'User' )
misc_={ misc_={
'version.gif':ImageFile('images/version.gif', globals()) 'version.gif':ImageFile('images/version.gif', globals())
} }
...@@ -110,26 +92,5 @@ def initialize(context): ...@@ -110,26 +92,5 @@ def initialize(context):
legacy=(AccessControl.User.manage_addUserFolder,), legacy=(AccessControl.User.manage_addUserFolder,),
) )
## Those both classes are relicts. We only withdraw them from the Add menu.
## This way people will stop using them. They are undocumented anyway.
## People also have the chance to softly migrate their data and stop using the
## versions they still use.
#context.registerClass(
# Version.Version,
# constructors=(Version.manage_addVersionForm,
# Version.manage_addVersion),
# icon='images/version.gif'
# )
#context.registerClass(
# Draft.Draft,
# constructors=(Draft.manage_addPrincipiaDraftForm,
# Draft.manage_addPrincipiaDraft),
# icon='images/draft.gif'
# )
context.registerZClass(ZClasses.ObjectManager.ZObjectManager)
context.registerHelp() context.registerHelp()
context.registerHelpTitle('Zope Help') context.registerHelpTitle('Zope Help')
Common Instance Property Sheet - Define properties for ZClasses.
Description
Common Instance Property Sheets allow ZClasses to define sets of
properties. A property sheets provides an editing view for the
properties and default values for the properties.
Individual instances of ZClasses have their own properties.
A property sheet provides a way to describe and edit a set of
properties.
Common Instance Property Sheet - Add: Create a new Common Instance Property Sheet.
Description
This view allows you to add a 'container object' that will enclose all the
properties for the ZClass.
Controls
'Id' -- Specifies the id of the Common Instance Property Sheet.
'Title' -- Specifies an optional title of the Common Instance
Property Sheet.
'Add' -- Creates the Common Instance Property Sheet.
...@@ -5,7 +5,6 @@ Product - Zope extension. ...@@ -5,7 +5,6 @@ Product - Zope extension.
Products allow you to extend Zope by creating new types of addable Zope Products allow you to extend Zope by creating new types of addable Zope
objects. objects.
A Product contains other objects such as ZClasses and Factories A Product contains other objects such as Factories which allows you
which allows you
to make your objects available via the product add list. to make your objects available via the product add list.
...@@ -27,8 +27,7 @@ class PropertySheet: ...@@ -27,8 +27,7 @@ class PropertySheet:
Return a namespace string usable as an xml namespace Return a namespace string usable as an xml namespace
for this property set. This may be an empty string if for this property set. This may be an empty string if
there is no default namespace for a given property sheet there is no default namespace for a given property sheet.
(especially property sheets added in ZClass definitions).
Permission -- Python only Permission -- Python only
......
...@@ -23,7 +23,7 @@ class PropertySheets: ...@@ -23,7 +23,7 @@ class PropertySheets:
instances. instances.
Objects that support property sheets (objects that support the Objects that support property sheets (objects that support the
PropertyManager interface or ZClass objects) have a PropertyManager interface) have a
'propertysheets' attribute (a PropertySheets instance) that is the 'propertysheets' attribute (a PropertySheets instance) that is the
collection of PropertySheet objects. The PropertySheets object collection of PropertySheet objects. The PropertySheets object
exposes an interface much like a Python mapping, so that exposes an interface much like a Python mapping, so that
......
Security - Define Permissions: Map permissions.
Description
The "Define Permissions" view is used to define how the operations
of this object (or objects that acquire permission settings from
this object) correspond to the operations defined by your product
or ZClass.
Permissions
Permissions are used to represent abstract operations or types of
usage. A permission may correspond to many low-level object
operations. Permissions provide a way to control access to
operations without having to list each operation explicitly.
When creating Products or ZClasses, we use high-level objects,
like DTML Methods to define operations. These high-level objects
have their own permissions, which represent abstract operations on
the low-level operations of these high-level objects.
When defining permissions for our products and ZClasses we need
to define what low-level operations these new permissions
correspond to. We could enumerate the low-level operations of
the high-level objects used to implement the operations of our
products or ZClasses, but this would be cumbersome, error prone,
and likely to break as the interfaces of the high-level objects
evolve.
What we do instead is to treat the permissions of the high-level
objects used to implement a Product or ZClass operations as the
low-level operations that the product or ZClass operations
abstract.
Controls
The view has a table with two columns. The first column lists the
permissions for an object. The second column specifies the
permissions that should have this permission in this product or
ZClass. For ZClass methods only permissions that are defined for
the ZClass are permitted.
In general any permissions that include operations that change
(mutate) an object should be disabled. Otherwise, a method could
be modified when used on an instance, such as a ZClass instance.
This interface is used to define how the operations of this object
(or objects that acquire permission settings from this object)
correspond to the operations defined by your product or ZClass.
**Note: The 'View' permission should be always mapped to the
'View' permission, since every user, even 'Anonymous User' has
this permission.**
'Permission for this object' -- The object permission to map.
'Permissions that correspond to (i.e. have) this permission' --
The Product or ZClass permission to map to.
'Change' -- Changes the permissions mapping.
ZClass - Define new Zope objects.
Description
ZClasses define new types of Zope objects.
ZClass - Add: Add a new ZClass
Description
This view allows you to create a new ZClass.
Controls
'Id' -- The id of the ZClass.
'Title' -- The optional title of the ZClass.
'Meta type' -- The name of the ZClass as it will appear in the
product add list.
'Create constructor objects' -- Create the necessary objects to
construct new ZClass instances. The created constructor objects are
a Zope Permission, a Zope Factory, an add method and an add form.
**Note: You must specify a 'Meta type' to create constructor objects**
'Base classes' -- Base classes of the ZClass.
To add a base class select it from the 'Unselected' list and
click the right arrow button. To remove a base class select it
from the 'Selected' list and click the left arrow button. The
names of base classes are divided into two parts separated by a
colon indicating the product name and the class name of the base
class. The order of Base classes is important.
'Include standard Zope persistent object base classes' -- Subclass
Zope persistence classes and thereby act as a normal persistent
object.
'Add' -- Creates the ZClass.
ZClass - Basic: Basic class attributes.
Description
This view allows you to manage the basic attributes of a ZClass.
Controls
'Title' -- The title of the ZClass.
'Meta type' -- The name of the ZClass as it appears in the product
add list.
'class id' -- The unique class identifier for the ZClass.
'icon' -- The path to the ZClass's icon.
'Icon image' -- Upload a new image file to sever as the ZClass's
icon. Use the 'Browse...' button to local a file to upload.
The uploaded icon file should be a 16x16 pixel GIF file.
'Change' -- Change the ZClass.
ZClass - Methods: Manage ZClass methods.
Description
This view allows you to manage ZClass methods.
A ZClass inherits methods from its base classes. It can also
contain methods which are managed through the web. This view
allows you to create and edit methods such as DTML Methods, ZSQL
Methods, and External Methods though the web. Methods that you
create through the web will be accessible as methods on instances
of the ZClass.
The creation and management of methods proceeds exactly like the
management of a Folder's contents. See "Folder - Contents". The
main difference between editing method objects and normal objects
is that methods have a 'Define Permissions' view in place of a
'Security' view. See "Security - Define Permissions".
If you create ZClasses inside the Methods view of a ZClass
instances of the inner class will be addable to instances of the
outer class. Typically the outer class will subclass
'ObjectManager' and the inner class will be only relevant inside
the outer class.
ZClass - Permissions: Select ZClass permissions.
Description
This view allows you to select permissions to be used by a ZClass.
When setting permissions for individual methods or property sheets
of a ZClass, you will be able to select from inherited permissions
and class permission which you set with this view.
Controls
'Class permissions' -- The permissions available to your ZClass in
addition to inherited permissions.
'Inherited permissions' -- Indicates the inherited permissions of
your ZClass.
'Change' -- Change Class permissions.
ZClass - Property Sheets: Manage ZClass property sheets.
Description
This view allows you to manage a ZClass's property sheets.
Property sheets provide a way to organize ZClass properties. A property
sheet defines default values for ZClass instance attributes and provides
an editing method for the attributes.
The creation and management of property sheets proceeds exactly like
the management of a Folder's contents. See "ObjectManager - Contents".
ZClass - Subobjects: Define suboject types.
Description
This view allows you to control what types of objects
are addable within instances of your ZClass.
Controls
Select one or more of the listed meta-types to indicate that
objects of these types can be added to instances of your ZClass.
'Objects should appear in folder lists' -- Controls whether or not
instances of your ZClass appear as folders in the left Zope
management frame.
'Change' -- Change subobject settings.
ZClass - Views: Define management views.
Description
This view allows you to manage a ZClass's views.
Views are managements screens that are available as tabs while
managing a Zope object. To provides through the web management for
your ZClass you need to define management views. Each management
view consists of a name, a method, and a help topic. When the
management view is selected by the user the view's method is
executed. Typically view methods are edit forms. Help topics
provide help for views. If a view has an associated help topic, a
help button will appear on the management view.
**Note: A view will not be visible to a user unless they have
adequate permissions to execute the view method.**
Controls
Editing Views
Views are listed one per line.
'[Checkbox]' -- Selects a view.
'Method' -- The method of the view.
'Help Topic' -- The help topic associated with the view.
'Change' -- Change the views.
'Delete' -- Delete the selected views.
'First' -- Moves the selected view to the beginning of the view
list. This allows you to change the order of the views.
Creating Views
'New' -- Allows you to create a new view. In the 'Name' field you
will be able to specify the label name of the view. The 'Method'
and 'Help Topic' field are the same as above.
'Name' -- The name of the view.
'Method' -- The method of the view.
'Help Topic' -- The help topic associated with the view.
'Add' -- Create a new view.
Zope Factory: Product creation facility.
Description
Zope Factories insert objects into the product add list.
Typically Factories are used to place ZClasses in the product add
list.
Zope Factory - Add: Create a Zope Factory.
Description
This view allows you to create a new Zope Factory.
Controls
'Id' -- The id of the Zope Factory.
'Title' -- The optional title of the Zope Factory.
'Add list name' -- The name that will appear on the in the product
add list. In the case of ZClasses this is normally the ZClass's
meta-type.
'Method' -- The method that is executed when the product is chosen
from the product add list. Typically this method is an add form.
'Generate' -- Create the Factory and add its entry to the product
add list.
Zope Factory - Edit: Edit Factory.
Description
This view allows you to edit a Zope Factory.
Controls
'Title' -- The optional title of the Zope Factory.
'Add list name' -- The name that will appear on the in the product
add list. In the case of ZClasses this is normally the ZClass's
meta-type.
'Method' -- The method that is executed when the product is chosen
from the product add list. Typically this method is an add form.
'Permission' -- The permission needed to execute the factory. If
the user does not have the Factory permission, the Factory's entry
will not show up in the product add list.
'Change' -- Change the Factory and update the product add list.
...@@ -3,5 +3,3 @@ Zope Permission: Define new Permissions. ...@@ -3,5 +3,3 @@ Zope Permission: Define new Permissions.
Description Description
Zope Permissions allow you to define new permissions. Zope Permissions allow you to define new permissions.
Typically new Permissions are associated with operations on ZClasses.
...@@ -62,7 +62,7 @@ class MountPoint(persistent.Persistent, Implicit): ...@@ -62,7 +62,7 @@ class MountPoint(persistent.Persistent, Implicit):
_v_data = None _v_data = None
_v_connect_error = None _v_connect_error = None
def __init__(self, path, params=None, classDefsFromRoot=1): def __init__(self, path, params=None, classDefsFromRoot=None):
''' '''
@arg path The path within the mounted database from which @arg path The path within the mounted database from which
to derive the root. to derive the root.
...@@ -74,10 +74,6 @@ class MountPoint(persistent.Persistent, Implicit): ...@@ -74,10 +74,6 @@ class MountPoint(persistent.Persistent, Implicit):
and use the existing database. Include the class name of and use the existing database. Include the class name of
the storage. For example, the storage. For example,
ZEO params might be "ZODB.ZEOClient localhost 1081". ZEO params might be "ZODB.ZEOClient localhost 1081".
@arg classDefsFromRoot If true (the default), MountPoint will
try to get ZClass definitions from the root database rather
than the mounted database.
''' '''
# The only reason we need a __mountpoint_id is to # The only reason we need a __mountpoint_id is to
# be sure we don't close a database prematurely when # be sure we don't close a database prematurely when
...@@ -90,7 +86,6 @@ class MountPoint(persistent.Persistent, Implicit): ...@@ -90,7 +86,6 @@ class MountPoint(persistent.Persistent, Implicit):
params = self.__mountpoint_id params = self.__mountpoint_id
self._params = repr(params) self._params = repr(params)
self._path = path self._path = path
self._classDefsFromRoot = classDefsFromRoot
def _createDB(self): def _createDB(self):
'''Gets the database object, usually by creating a Storage object '''Gets the database object, usually by creating a Storage object
...@@ -111,9 +106,6 @@ class MountPoint(persistent.Persistent, Implicit): ...@@ -111,9 +106,6 @@ class MountPoint(persistent.Persistent, Implicit):
db = self._createDB() db = self._createDB()
newMount = 1 newMount = 1
dbs[params] = (db, {self.__mountpoint_id:1}) dbs[params] = (db, {self.__mountpoint_id:1})
if getattr(self, '_classDefsFromRoot', 1):
db.classFactory = parentClassFactory
else: else:
db, mounts = dbInfo db, mounts = dbInfo
# Be sure this object is in the list of mount points. # Be sure this object is in the list of mount points.
......
...@@ -23,8 +23,8 @@ from App.special_dtml import DTMLFile ...@@ -23,8 +23,8 @@ from App.special_dtml import DTMLFile
class CatalogAware: class CatalogAware:
""" This is a Mix-In class to make objects automaticly catalog and """ This is a Mix-In class to make objects automaticly catalog and
uncatalog themselves in Zope, and to provide some other basic uncatalog themselves in Zope, and to provide some other basic
attributes that are useful to catalog. Note that if your class or attributes that are useful to catalog. Note that if your class
ZClass subclasses CatalogAware, it will only catalog itself when subclasses CatalogAware, it will only catalog itself when
it is added or copied in Zope. If you make changes to your own it is added or copied in Zope. If you make changes to your own
object, you are responsible for calling your object's index_object object, you are responsible for calling your object's index_object
method. """ method. """
......
...@@ -19,8 +19,8 @@ from App.special_dtml import DTMLFile ...@@ -19,8 +19,8 @@ from App.special_dtml import DTMLFile
class CatalogAware: class CatalogAware:
""" This is a Mix-In class to make objects automaticly catalog and """ This is a Mix-In class to make objects automaticly catalog and
uncatalog themselves in Zope, and to provide some other basic uncatalog themselves in Zope, and to provide some other basic
attributes that are useful to catalog. Note that if your class or attributes that are useful to catalog. Note that if your class
ZClass subclasses CatalogAware, it will only catalog itself when subclasses CatalogAware, it will only catalog itself when
it is added or copied in Zope. If you make changes to your own it is added or copied in Zope. If you make changes to your own
object, you are responsible for calling your object's index_object object, you are responsible for calling your object's index_object
method. """ method. """
...@@ -119,16 +119,3 @@ class CatalogAware: ...@@ -119,16 +119,3 @@ class CatalogAware:
for item in obj.objectValues(): for item in obj.objectValues():
self.reindex_all(item) self.reindex_all(item)
return 'done!' return 'done!'
class CatalogPathAware(CatalogAware):
"""
This is a stub class that gets registered in __init__.py as a
ZClass base class. Its reason for existance is to make the name
that shows up in the ZClass Product list different than 'ZCatalog:
CatalogAware', which is the name registered by
CatalogAwareness.CatalogAware. The fix should *really* be to
change the product registry to keep the whole module/class path
and to make the ZClass add UI show the whole path, but this is
nontrivial, we don't want to spend a lot of time on ZClasses, and
this works.
"""
...@@ -99,10 +99,9 @@ ZCatalog Tutorial ...@@ -99,10 +99,9 @@ ZCatalog Tutorial
Most the work is done in the first step, which is getting objects Most the work is done in the first step, which is getting objects
into the index. This is done in two ways. First, if your objects into the index. This is done in two ways. First, if your objects
are ZCatalog-aware they automatically update the index when they are ZCatalog-aware they automatically update the index when they
are added, edited or directly deleted. A ZCatalog-aware object is are added, edited or directly deleted. *Directly deleted* means
one that is an instance of a 'Z Class' that informs the 'ZCatalog' the object was deleted from a Folder, not the deletion of a
of changes. *Directly deleted* means the object was deleted from containing Folder.
a Folder, not the deletion of a containing Folder.
The second way that site contents get updated is by "finding" The second way that site contents get updated is by "finding"
information "into" the 'ZCatalog'. An operation based on Zope's information "into" the 'ZCatalog'. An operation based on Zope's
...@@ -136,300 +135,6 @@ ZCatalog Tutorial ...@@ -136,300 +135,6 @@ ZCatalog Tutorial
ZCatalogs can also be queried directly from DTML, as shown in the ZCatalogs can also be queried directly from DTML, as shown in the
example below. example below.
Example using Z Classes
The first example shows how to give your Zope site a long-desired
feature: full text-searches of your content. The example assumes
you already have a number of DTML Methods/Documents to catalog.
o Install 'ZCatalog' as instructed above
o In the root folder of your Zope server, add a 'ZCatalog'.
o Type in the id 'catalog' and hit 'Add'.
You now have a brand new 'ZCatalog' named 'catalog' in your root
folder.
o Click on it.
Now you are looking at the 'ZCatalog' 'Contents' view. It says
the catalog is empty. We'll catalog some objects in a moment, but
first we have to tell it what portions of objects we are
specifically interested in.
o Click on 'Indexes'.
This management view is where the attributes to be indexed are
defined.
o In the 'Add index' field, type 'raw'.
o Click 'Add'.
Now that the indexes are defined, a set of objects can be selected
for cataloging.
o Click on 'Find items to ZCatalog'.
For this example, we are only interested in DTML Documents and
Methods.
o Deselect 'All type'.
o Select 'DTML Method' and 'DTML Document'.
o Click 'Find'.
ZCatalog will report how many items it found, and then present an
interface for excluding specific objects.
o Click 'Catalog Items'.
Great, now that the catalog is stocked, we can create a user
interface to it.
o Return to the root folder's management view.
o Add a 'Z Search Interface'.
'ZCatalog' participates in the Zope Search architecture. You
simply have to fill in this form, and a basic user interface will
be created.
o Select 'catalog' in the list beside 'Select one or more searchable
objects'.
o Beside 'Report Id', type 'report'.
o Beside 'Search Input Id', type 'search'.
'report' and 'search' are the Ids of two DTML Methods which will
be created in your root folder.
o Click 'Add'.
Congratulations, if all has gone well, you can now find references
to any word in your DTML pages. Try it by viewing 'search'. Type
a common word in the 'Raw' field, and you should be presented with
a list of hits. However, none of the results returned can be
clicked on. To fix this, go to the management view of 'report'.
'report' is called by 'search' to display the results from
'catalog'. 'report' is just a simple '<!--#in catalog-->' loop
with a few refinements. 'catalog' knows which results to return
by looking at the REQUEST variable, which contains the input from
the 'search' form.
o In the source of 'report', find the following line::
<tr><!--#var title--></tr>
o Replace it with this::
<tr>
<a href="<!--#var "catalog.getpath(data_record_id_)"-->">
<!--#var title-->
</a>
</tr>
This is a little confusing at first. Keep in mind that ZCatalog
does not return a list of your database objects. What it returns
are actually fairly unintelligent instances of a Record subclass.
These record objects contain copies of data from attributes of
catalog objects. The 'ZCatalog' 'MetaData Table' view defines
which attributes are copied.
(By default, these record objects are just SLIGHTLY more
intelligent than a raw tuple. 'Catalog' can be told to use a
custom, intelligent class for results. Please see the 'Catalog'
__init__ method in 'lib/python/Products/ZCatalog/Catalog.py' for
more information.)
Fortunately, ZCatalog provides a utility function for going from
result objects to the object's path. It is called, aptly enough,
'getpath'. 'getpath' expects to be passed the unique integer
identifier of the cataloged object. Results store that id as
'data_record_id_'.
Commit this change, and perform another search. Now the title can
be clicked on to take you to the full page.
Example cataloging custom objects
As if full-text searches of your entire site weren't good enough,
ZCatalog can also catalog Z Classes, Products, and in fact any
Python object you can put in a ZODB. Here is an example using a Z
Class, but the principles apply to any kind of object.
First, we're going to need something to catalog. Follow the 'Z
Class' tutorial to create the CD 'Z Class'. Back? Good.
o Create a folder, 'CDs', and create a number of instances of
the CD Z Class in it.
'cd1' through 'cd5' should be plenty. Remember to fill each of
them in from their Properties view.
Now we want to create a searchable catalog of CDs.
o Go to the 'CDs' folder and create a 'ZCatalog' with an ID 'cd_cat'.
o Click on the objects Indexes view.
This screen shows that, by default, 'ZCatalog' is interested in an
object's 'id','title', 'meta_type', and
'bobobase_modification_time'. You will almost always want to
index additional information. In this case, we would also like to
index the artist and description of CDs.
o Type 'artist' into the 'Add Index' field.
For the sake of example, we're going to use a FieldIndex index for
artist. This will give us the option of putting an HTML SELECT
box for artists on the search form.
o Select FieldIndex from the Index type drop down, and click
'Add'.
o Also add an index for 'description', but leave TextIndex
selected.
This will allow us to search for individual words within the
description.
o Click on 'MetaData Table'.
This is where we tell the 'ZCatalog' what attributes of cataloged
objects to cache. These cached values are available from search
results without having to look up the actual indexed object. The
tradeoff for the speed is extra memory, as information from the
content is duplicated in the 'ZCatalog'.
You will probably want to keep the schema light-weight, so we're
not going to add 'description' to it. Type 'artist' in the 'Add
column' field and click 'Add'.
o Click on the 'Find Items to Catalog' view.
This is the interface you use to tell the 'ZCatalog' which items
to index. Right now, beside 'Find objects of type:', 'All types'
is selected.
o Deselect 'All types'.
O Scroll down and select CD.
You could use the rest of the form to be more specific, but since
we want to catalog all the CDs,
o Click 'Find'.
'ZCatalog' will report 'Found 5 items.' It is now giving you an
opportunity to exclude some of the matched items from the index.
Again, we want all of them, so,
o Click 'Catalog Items'.
You should at this point see a list of the indexed objects. Also
of note is the 'Update Catalog' button. You have to use it
whenever you want your 'ZCatalog' to notice changes you've made to
the objects it's indexed.
Creating Search Forms And Result Reports
This catalog isn't much good without some way of querying it.
o Go back to your 'CDs' folder's management screen and add a Z
Search Interface.
The search add form will automatically detect your cd_cat
'ZCatalog' and offer it as a searchable document. Make sure it is
selected.
o Fill in 'cd_report' for 'Report ID' and 'cd_search' for
'Search Input ID'.
Those are the ids of two DTML methods that will be generated in
the 'CDs' folder.
o Click 'Add'.
o View the 'cd_search' Catalog (at, for example,
http://localhost:9673/CDs/cd_search).
You will see a basic search interface, with fields for searching
on 'title', modification date, 'id', 'artist', 'meta type' and
'description'. If you fill in one more more of the fields and
click 'Submit Query', cd_report will be displayed. It is passed
the search criteria and uses it to get a list from cd_cat to
iterate over. It is merely displaying the information from the
ZCatalog's MetaData table, but of course it can be enriched.
Try a few more searches. You'll find that you can type any single
word from the title or description and get a match, but for artist
you must type the exact string. That's because artist was indexed
as a FieldIndex, which gives us an opportunity to present a more
convenient interface.
Go back to the 'cd_search' management interface, and change
it's source to look like this::
<xmp>
<!--#var standard_html_header-->
<form action="cd_report" method="get">
<h2><!--#var document_title--></h2>
Enter query parameters:<br><table>
<tr><th>Title</th>
<td><input name="title"
width=30 value=""></td></tr>
<tr><th>Artist</th>
<td>
<select name="artist">
<option value="">All</option>
<!--#in expr="cd_cat.uniqueValuesFor('artist')"-->
<option value="<!--#var sequence-item-->">
<!--#var sequence-item-->
</option>
<!--#/in-->
</select>
</td>
</tr>
<tr><th>Description</th>
<td><input name="description"
width=30 value=""></td></tr>
<tr><td colspan=2 align=center>
<input type="SUBMIT" name="SUBMIT" value="Submit Query">
</td></tr>
</table>
</form>
<!--#var standard_html_footer-->
</xmp>
This is a search form somewhat more appropriate for the CD 'Z
Class'. Unrelated fields have been removed, and the 'artist'
field has been changed to a drop-down menu. Let's augment the
output of 'cd_report' to make the title a link to the actual CD
object.
Taking a look at 'cd_report', note that the search results are
obtained with a simple '<!--#in cd_cat ...-->' tag. The search
criteria is automatically obtained by the 'ZCatalog' from the form
input. The line we're interested in is this one::
<td><!--#var title--></td>
Change it to read::
<td>
<a href="<!--#var "cd_cat.getpath(data_record_id_)"-->">
<!--#var title-->
</a>
</td>
Now, assuming you have added the index_html document template to
your CD 'Z Class', clicking on a search result will take you to
the CD's detailed display.
Using 'ZCatalog' In A Zope Site Using 'ZCatalog' In A Zope Site
The 'ZCatalog' provides high-speed access to what is on your site. The 'ZCatalog' provides high-speed access to what is on your site.
......
...@@ -13,26 +13,7 @@ ...@@ -13,26 +13,7 @@
"""ZCatalog product""" """ZCatalog product"""
import ZCatalog, CatalogAwareness, CatalogPathAwareness import ZCatalog
# BBB: ZClasses are deprecated but we don't want the warning to appear here
import warnings
warnings.filterwarnings('ignore', message='^ZClasses', append=1)
try:
from ZClasses import createZClassForBase
finally:
del warnings.filters[-1]
try:
del __warningregistry__
except NameError:
pass
createZClassForBase( ZCatalog.ZCatalog , globals()
, 'ZCatalogBase', 'ZCatalog' )
createZClassForBase( CatalogAwareness.CatalogAware, globals()
, 'CatalogAwareBase', 'CatalogAware' )
createZClassForBase( CatalogPathAwareness.CatalogPathAware, globals()
, 'CatalogPathAwareBase', 'CatalogPathAware' )
def initialize(context): def initialize(context):
context.registerClass( context.registerClass(
......
...@@ -48,7 +48,6 @@ automatically be provided under that name when the script is called. ...@@ -48,7 +48,6 @@ automatically be provided under that name when the script is called.
This is the <dtml-with expr="aq_inner.aq_parent">&dtml-meta_type; This is the <dtml-with expr="aq_inner.aq_parent">&dtml-meta_type;
"&dtml.missing.html_quote-title_or_id;"</dtml-with>, in which this "&dtml.missing.html_quote-title_or_id;"</dtml-with>, in which this
script is located. This doesn't change unless you move the script. script is located. This doesn't change unless you move the script.
If the script is in a ZClass, the Container is the class instance.
<br /><br /> <br /><br />
Recommended value: <code>container</code> Recommended value: <code>container</code>
</div> </div>
......
...@@ -13,18 +13,11 @@ ...@@ -13,18 +13,11 @@
__doc__='''Generic Database adapter''' __doc__='''Generic Database adapter'''
__version__='$Revision: 1.116 $'[11:-2] __version__='$Revision: 1.116 $'[11:-2]
import base64
from cPickle import dumps
from cPickle import loads
from cStringIO import StringIO from cStringIO import StringIO
import marshal
import os
import re import re
import string import string
import sys import sys
from time import time from time import time
from zlib import compress
from zlib import decompress
from AccessControl.DTML import RestrictedDTML from AccessControl.DTML import RestrictedDTML
from AccessControl.Permissions import change_database_methods from AccessControl.Permissions import change_database_methods
...@@ -35,7 +28,6 @@ from AccessControl.SecurityInfo import ClassSecurityInfo ...@@ -35,7 +28,6 @@ from AccessControl.SecurityInfo import ClassSecurityInfo
from AccessControl.SecurityManagement import getSecurityManager from AccessControl.SecurityManagement import getSecurityManager
from Acquisition import Implicit from Acquisition import Implicit
from App.class_init import InitializeClass from App.class_init import InitializeClass
from App.Dialogs import MessageDialog
from App.Extensions import getBrain from App.Extensions import getBrain
from App.special_dtml import DTMLFile from App.special_dtml import DTMLFile
from DocumentTemplate import HTML from DocumentTemplate import HTML
...@@ -51,7 +43,6 @@ from zExceptions import BadRequest ...@@ -51,7 +43,6 @@ from zExceptions import BadRequest
from Aqueduct import BaseQuery from Aqueduct import BaseQuery
from Aqueduct import custom_default_report from Aqueduct import custom_default_report
from Aqueduct import decodestring
from Aqueduct import default_input_form from Aqueduct import default_input_form
from Aqueduct import parse from Aqueduct import parse
from RDB import File from RDB import File
...@@ -102,7 +93,6 @@ class DA(BaseQuery, ...@@ -102,7 +93,6 @@ class DA(BaseQuery,
cache_time_=0 cache_time_=0
max_cache_=100 max_cache_=100
class_name_=class_file_='' class_name_=class_file_=''
_zclass=None
allow_simple_one_argument_traversal=None allow_simple_one_argument_traversal=None
template_class=SQL template_class=SQL
connection_hook=None connection_hook=None
...@@ -204,7 +194,7 @@ class DA(BaseQuery, ...@@ -204,7 +194,7 @@ class DA(BaseQuery,
security.declareProtected(change_database_methods, 'manage_advanced') security.declareProtected(change_database_methods, 'manage_advanced')
def manage_advanced(self, max_rows, max_cache, cache_time, def manage_advanced(self, max_rows, max_cache, cache_time,
class_name, class_file, direct=None, class_name, class_file, direct=None,
REQUEST=None, zclass='', connection_hook=None): REQUEST=None, connection_hook=None):
"""Change advanced properties """Change advanced properties
The arguments are: The arguments are:
...@@ -253,21 +243,9 @@ class DA(BaseQuery, ...@@ -253,21 +243,9 @@ class DA(BaseQuery,
self.connection_hook = connection_hook self.connection_hook = connection_hook
if zclass:
for d in self.aq_acquire('_getProductRegistryData')('zclasses'):
if ("%s/%s" % (d.get('product'),d.get('id'))) == zclass:
self._zclass=d['meta_class']
break
if REQUEST is not None: if REQUEST is not None:
m="ZSQL Method advanced settings have been set" m="ZSQL Method advanced settings have been set"
return self.manage_advancedForm(self,REQUEST,manage_tabs_message=m) return self.manage_advancedForm(self,REQUEST,manage_tabs_message=m)
## return self.manage_editedDialog(REQUEST)
#def getFindContent(self):
# """Return content for use by the Find machinery."""
# return '%s\n%s' % (self.arguments_src, self.src)
security.declareProtected(view_management_screens, 'PrincipiaSearchSource') security.declareProtected(view_management_screens, 'PrincipiaSearchSource')
def PrincipiaSearchSource(self): def PrincipiaSearchSource(self):
...@@ -493,8 +471,6 @@ class DA(BaseQuery, ...@@ -493,8 +471,6 @@ class DA(BaseQuery,
if hasattr(self, 'aq_parent'): if hasattr(self, 'aq_parent'):
p=self.aq_parent p=self.aq_parent
if self._isBeingAccessedAsZClassDefinedInstanceMethod():
p=p.aq_parent
else: else:
p=None p=None
...@@ -529,16 +505,13 @@ class DA(BaseQuery, ...@@ -529,16 +505,13 @@ class DA(BaseQuery,
else: else:
brain=self._v_brain=getBrain(self.class_file_, self.class_name_) brain=self._v_brain=getBrain(self.class_file_, self.class_name_)
zc=self._zclass
if zc is not None: zc=zc._zclass_
if type(result) is type(''): if type(result) is type(''):
f=StringIO() f=StringIO()
f.write(result) f.write(result)
f.seek(0) f.seek(0)
result = File(f,brain,p, zc) result = File(f,brain,p, None)
else: else:
result = Results(result, brain, p, zc) result = Results(result, brain, p, None)
columns = result._searchable_result_columns() columns = result._searchable_result_columns()
if test__ and columns != self._col: if test__ and columns != self._col:
self._col=columns self._col=columns
...@@ -573,30 +546,9 @@ class DA(BaseQuery, ...@@ -573,30 +546,9 @@ class DA(BaseQuery,
def connected(self): def connected(self):
return getattr(getattr(self, self.connection_id), 'connected')() return getattr(getattr(self, self.connection_id), 'connected')()
security.declareProtected(change_database_methods,
'manage_product_zclass_info')
def manage_product_zclass_info(self):
r=[]
Z=self._zclass
Z=getattr(Z, 'aq_self', Z)
for d in self.aq_acquire('_getProductRegistryData')('zclasses'):
z=d['meta_class']
if hasattr(z._zclass_,'_p_deactivate'):
# Eek, persistent
continue
x={}
x.update(d)
x['selected'] = (z is Z) and 'selected' or ''
del x['meta_class']
r.append(x)
return r
InitializeClass(DA) InitializeClass(DA)
ListType=type([]) ListType=type([])
class Traverse(Base): class Traverse(Base):
"""Helper class for 'traversing' searches during URL traversal """Helper class for 'traversing' searches during URL traversal
......
...@@ -91,38 +91,6 @@ directory of this Zope installation. ...@@ -91,38 +91,6 @@ directory of this Zope installation.
<input name="class_file" size="30" value="&dtml-class_file_;"> <input name="class_file" size="30" value="&dtml-class_file_;">
</td> </td>
</tr> </tr>
<dtml-if manage_product_zclass_info>
<tr>
<td align="left" valign="top" colspan="2">
<div class="form-text">
<br />
You may specify a <strong>ZClass</strong> for the data records.
</div>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
ZClass
</div>
</td>
<td align="left" valign="top">
<div class="form-element">
<select name="zclass">
<option value="">No ZClass</option>
<dtml-in manage_product_zclass_info mapping>
<dtml-with "_(v='%s/%s' % (product, id))">
<option value="&dtml-v;" &dtml-selected;>
&dtml-product; &dtml-id;
(&dtml-meta_type;)</option>
</dtml-with>
</dtml-in>
</select>
</div>
</td>
</tr>
</dtml-if>
<tr> <tr>
<td align="left" valign="top"> <td align="left" valign="top">
</td> </td>
......
...@@ -297,8 +297,6 @@ Module utils ...@@ -297,8 +297,6 @@ Module utils
setupCoreSessions(app=None) setupCoreSessions(app=None)
setupZGlobals(app=None)
setupSiteErrorLog(app=None) setupSiteErrorLog(app=None)
startZServer(number_of_threads=1, log=None) startZServer(number_of_threads=1, log=None)
......
...@@ -106,8 +106,6 @@ What You Get ...@@ -106,8 +106,6 @@ What You Get
- **'setupCoreSessions'** creates the Zope sessioning objects in the test ZODB. - **'setupCoreSessions'** creates the Zope sessioning objects in the test ZODB.
- **'setupZGlobals'** creates the ZGlobals BTree required by ZClasses.
- **'setupSiteErrorLog'** creates the error_log object required by ZPublisher. - **'setupSiteErrorLog'** creates the error_log object required by ZPublisher.
- **'startZServer'** starts a ZServer thread on the local host. Use this if the - **'startZServer'** starts a ZServer thread on the local host. Use this if the
......
...@@ -67,16 +67,6 @@ def setupCoreSessions(app): ...@@ -67,16 +67,6 @@ def setupCoreSessions(app):
transaction.commit() transaction.commit()
@layer.appcall
def setupZGlobals(app):
'''Sets up the ZGlobals BTree required by ZClasses.'''
root = app._p_jar.root()
if not root.has_key('ZGlobals'):
from BTrees.OOBTree import OOBTree
root['ZGlobals'] = OOBTree()
transaction.commit()
@layer.appcall @layer.appcall
def setupSiteErrorLog(app): def setupSiteErrorLog(app):
'''Sets up the error_log object required by ZPublisher.''' '''Sets up the error_log object required by ZPublisher.'''
...@@ -158,7 +148,6 @@ def makelist(arg): ...@@ -158,7 +148,6 @@ def makelist(arg):
__all__ = [ __all__ = [
'setupCoreSessions', 'setupCoreSessions',
'setupSiteErrorLog', 'setupSiteErrorLog',
'setupZGlobals',
'startZServer', 'startZServer',
'importObjectFromFile', 'importObjectFromFile',
'appcall', 'appcall',
......
...@@ -1479,7 +1479,7 @@ class FileUpload: ...@@ -1479,7 +1479,7 @@ class FileUpload:
''' '''
# Allow access to attributes such as headers and filename so # Allow access to attributes such as headers and filename so
# that ZClass authors can use DTML to work with FileUploads. # that protected code can use DTML to work with FileUploads.
__allow_access_to_unprotected_subobjects__ = 1 __allow_access_to_unprotected_subobjects__ = 1
def __init__(self, aFieldStorage): def __init__(self, aFieldStorage):
......
...@@ -18,12 +18,7 @@ def ClassFactory(jar, module, name, ...@@ -18,12 +18,7 @@ def ClassFactory(jar, module, name,
_silly=('__doc__',), _globals={}, _silly=('__doc__',), _globals={},
): ):
try: try:
if module[:1]=='*':
# ZCLass! Yee ha!
return jar.root()['ZGlobals'][module]
else:
m=__import__(module, _globals, _globals, _silly) m=__import__(module, _globals, _globals, _silly)
return getattr(m, name) return getattr(m, name)
except: except:
return OFS.Uninstalled.Broken(jar, None, (module, name)) return OFS.Uninstalled.Broken(jar, None, (module, name))
...@@ -317,7 +317,7 @@ def minimalClassFactory(jar, module, name, ...@@ -317,7 +317,7 @@ def minimalClassFactory(jar, module, name,
def simpleClassFactory(jar, module, name, def simpleClassFactory(jar, module, name,
_silly=('__doc__',), _globals={}, _silly=('__doc__',), _globals={},
): ):
"""Class factory without ZClass support. """Class factory.
""" """
import OFS.Uninstalled import OFS.Uninstalled
try: try:
...@@ -326,28 +326,6 @@ def simpleClassFactory(jar, module, name, ...@@ -326,28 +326,6 @@ def simpleClassFactory(jar, module, name,
except: except:
return OFS.Uninstalled.Broken(jar, None, (module, name)) return OFS.Uninstalled.Broken(jar, None, (module, name))
def zopeClassFactory(jar, module, name,
_silly=('__doc__',), _globals={},
):
"""Class factory with ZClass support.
"""
import OFS.Uninstalled
try:
if module[:1]=='*':
# ZCLass! Yee ha!
return jar.root()['ZGlobals'][module]
else:
m=__import__(module, _globals, _globals, _silly)
return getattr(m, name)
except:
return OFS.Uninstalled.Broken(jar, None, (module, name))
# There used to be an "autoClassFactory" whose docstring read "If not the root
# connection, use the class factory from the root database, otherwise use the
# Zope class factory." This no longer works with the implementation of
# mounted databases, so we just use the zopeClassFactory as the default
try: try:
from zope.app.twisted.server import ServerFactory from zope.app.twisted.server import ServerFactory
class TwistedServerFactory(ServerFactory): class TwistedServerFactory(ServerFactory):
......
...@@ -234,7 +234,7 @@ ...@@ -234,7 +234,7 @@
</key> </key>
<key name="class-factory" datatype=".importable_name" <key name="class-factory" datatype=".importable_name"
default="Zope2.Startup.datatypes.zopeClassFactory"> default="Zope2.Startup.datatypes.simpleClassFactory">
<description> <description>
Change the class factory function a database uses on a Change the class factory function a database uses on a
per-database basis to support different class factory policy. per-database basis to support different class factory policy.
...@@ -244,7 +244,7 @@ ...@@ -244,7 +244,7 @@
<key name="container-class" datatype="string"> <key name="container-class" datatype="string">
<description> <description>
Change the contiainer class a (mounted) database uses on a Change the container class a (mounted) database uses on a
per-database basis to support a different container than a plain per-database basis to support a different container than a plain
Folder. Use a Python dotted-path name to specify the container class. Folder. Use a Python dotted-path name to specify the container class.
</description> </description>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment