Back to index

plone3  3.1.7
relativepath.py
Go to the documentation of this file.
00001 #  ATContentTypes http://sf.net/projects/collective/
00002 #  Archetypes reimplementation of the CMF core types
00003 #  Copyright (c) 2003-2005 AT Content Types development team
00004 #
00005 #  This program is free software; you can redistribute it and/or modify
00006 #  it under the terms of the GNU General Public License as published by
00007 #  the Free Software Foundation; either version 2 of the License, or
00008 #  (at your option) any later version.
00009 #
00010 #  This program is distributed in the hope that it will be useful,
00011 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 #  GNU General Public License for more details.
00014 #
00015 #  You should have received a copy of the GNU General Public License
00016 #  along with this program; if not, write to the Free Software
00017 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 #
00019 """ Topic:
00020 
00021 """
00022 
00023 __author__  = 'Alec Mitchell, Danny Bloemendaal'
00024 __docformat__ = 'restructuredtext'
00025 # __old_name__ = 'Products.ATContentTypes.types.criteria.ATPathCriterion'
00026 
00027 from Products.CMFCore.permissions import View
00028 from AccessControl import ClassSecurityInfo
00029 
00030 from Products.Archetypes.public import Schema, DisplayList
00031 from Products.Archetypes.public import BooleanField, StringField
00032 from Products.Archetypes.public import BooleanWidget, SelectionWidget, StringWidget
00033 from Products.Archetypes.Referenceable import Referenceable
00034 
00035 from Products.ATContentTypes.criteria import registerCriterion
00036 from Products.ATContentTypes.criteria import PATH_INDICES
00037 from Products.ATContentTypes.interfaces import IATTopicSearchCriterion
00038 from Products.ATContentTypes.permission import ChangeTopics
00039 from Products.ATContentTypes.criteria.base import ATBaseCriterion
00040 from Products.ATContentTypes.criteria.schemata import ATBaseCriterionSchema
00041 
00042 from Products.CMFCore.utils import getToolByName
00043 
00044 ATRelativePathCriterionSchema = ATBaseCriterionSchema + Schema((
00045     StringField('relativePath',
00046                 default='..',
00047                 widget=StringWidget(label='Relative path', 
00048                                     label_msgid="label_relativepath_criteria_customrelativepath",
00049                                     description_msgid="help_relativepath_criteria_customrelativepath",
00050                                     i18n_domain="plone",
00051                                     description="Enter a relative path e.g.: <br /> '..' for the parent folder <br /> '../..' for the parent's parent <br />'../somefolder' for a sibling folder")),
00052     BooleanField('recurse',
00053                 mode="rw",
00054                 write_permission=ChangeTopics,
00055                 accessor="Recurse",
00056                 default=False,
00057                 widget=BooleanWidget(
00058                     label="Search Sub-Folders",
00059                     label_msgid="label_path_criteria_recurse",
00060                     description="",
00061                     description_msgid="help_path_criteria_recurse",
00062                     i18n_domain="plone"),
00063                 ),
00064     ))
00065 
00066 class ATRelativePathCriterion(ATBaseCriterion):
00067     """A path criterion"""
00068 
00069     __implements__ = ATBaseCriterion.__implements__ + (IATTopicSearchCriterion, )
00070     security       = ClassSecurityInfo()
00071     schema         = ATRelativePathCriterionSchema
00072     meta_type      = 'ATRelativePathCriterion'
00073     archetype_name = 'Relative Path Criterion'
00074     shortDesc      = 'Location in site relative to the current location'
00075 
00076     def getNavTypes(self):
00077         ptool = self.plone_utils
00078         nav_types = ptool.typesToList()
00079         return nav_types
00080 
00081     security.declareProtected(View, 'getCriteriaItems')
00082     def getCriteriaItems(self):
00083         result = []
00084         depth = (not self.Recurse() and 1) or -1
00085         relPath = self.getRelativePath()
00086         
00087         # sanitize a bit: you never know, with all those windoze users out there
00088         relPath = relPath.replace("\\","/") 
00089 
00090         # get the path to the portal object 
00091         portalPath = list(getToolByName(self, 'portal_url').getPortalObject().getPhysicalPath())
00092     
00093         if relPath[0]=='/':
00094             # someone didn't enter a relative path.
00095             # simply use that one, relative to the portal
00096             path = '/'.join(portalPath) + relPath
00097         elif relPath=='..' or relPath=='../':
00098             # do a shortcut
00099             path = '/'.join(self.aq_parent.aq_parent.getPhysicalPath())
00100         else:
00101             folders = relPath.split('/')
00102 
00103             # set the path to the collections path
00104             path = list(self.aq_parent.getPhysicalPath()) 
00105             
00106             # now construct an aboslute path based on the relative custom path
00107             # eat away from 'path' whenever we encounter a '..' in the relative path
00108             # apend all other elements other than ..
00109             for folder in folders:
00110                 if folder == '..':
00111                     # chop off one level from path
00112                     if path == portalPath:
00113                         # can't chop off more
00114                         # just return this path and leave the loop
00115                         break
00116                     else:
00117                         path = path[:-1]
00118                 elif folder == '.': 
00119                     # don't really need this but for being complete
00120                     # strictly speaking some user may use a . aswell
00121                     pass # do nothing
00122                 else:
00123                     path.append(folder)
00124             path = '/'.join(path)
00125 
00126         if path is not '':
00127             result.append((self.Field(), {'query': path, 'depth': depth}))
00128 
00129         return tuple(result)
00130 
00131 
00132 registerCriterion(ATRelativePathCriterion, PATH_INDICES)