/kernel/classes/ezcontentobjecttreenode.php
PHP | 6134 lines | 4744 code | 572 blank | 818 comment | 610 complexity | 9d688ed6a4d53f7b14692975e5449f27 MD5 | raw file
Possible License(s): GPL-2.0
Large files files are truncated, but you can click here to view the full file
- <?php
- //
- // Definition of eZContentObjectTreeNode class
- //
- // Created on: <10-Jul-2002 19:28:22 sp>
- //
- // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
- // SOFTWARE NAME: eZ Publish
- // SOFTWARE RELEASE: 4.1.x
- // COPYRIGHT NOTICE: Copyright (C) 1999-2011 eZ Systems AS
- // SOFTWARE LICENSE: GNU General Public License v2.0
- // NOTICE: >
- // This program is free software; you can redistribute it and/or
- // modify it under the terms of version 2.0 of the GNU General
- // Public License as published by the Free Software Foundation.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of version 2.0 of the GNU General
- // Public License along with this program; if not, write to the Free
- // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- // MA 02110-1301, USA.
- //
- //
- // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
- //
- /*! \file
- */
- /*!
- \class eZContentObjectTreeNode ezcontentobjecttreenode.php
- \brief The class eZContentObjectTreeNode does
- \verbatim
- Some algorithms
- ----------
- 1. Adding new Node
- Enter 1 - parent_node
- 2 - contentobject_id, ( that is like a node value )
- (a) - get path_string, depth for parent node to built path_string and to count depth for new one
- (c) - calculating attributes for new node and inserting it
- Returns node_id for added node
- 2. Deleting node ( or subtree )
- Enter - node_id
- 3. Move subtree in tree
- Enter node_id,new_parent_id
- 4. fetching subtree
- \endverbatim
- */
- class eZContentObjectTreeNode extends eZPersistentObject
- {
- const SORT_FIELD_PATH = 1;
- const SORT_FIELD_PUBLISHED = 2;
- const SORT_FIELD_MODIFIED = 3;
- const SORT_FIELD_SECTION = 4;
- const SORT_FIELD_DEPTH = 5;
- const SORT_FIELD_CLASS_IDENTIFIER = 6;
- const SORT_FIELD_CLASS_NAME = 7;
- const SORT_FIELD_PRIORITY = 8;
- const SORT_FIELD_NAME = 9;
- const SORT_FIELD_MODIFIED_SUBNODE = 10;
- const SORT_FIELD_NODE_ID = 11;
- const SORT_FIELD_CONTENTOBJECT_ID = 12;
- const SORT_ORDER_DESC = 0;
- const SORT_ORDER_ASC = 1;
- /*!
- Constructor
- */
- function eZContentObjectTreeNode( $row = array() )
- {
- $this->eZPersistentObject( $row );
- }
- static function definition()
- {
- static $definition = array( "fields" => array( "node_id" => array( 'name' => "NodeID",
- 'datatype' => 'integer',
- 'default' => 0,
- 'required' => true ),
- "parent_node_id" => array( 'name' => "ParentNodeID",
- 'datatype' => 'integer',
- 'default' => 0,
- 'required' => true,
- 'foreign_class' => 'eZContentObjectTreeNode',
- 'foreign_attribute' => 'node_id',
- 'multiplicity' => '1..*' ),
- "main_node_id" => array( 'name' => "MainNodeID",
- 'datatype' => 'integer',
- 'default' => 0,
- 'required' => true,
- 'foreign_class' => 'eZContentObjectTreeNode',
- 'foreign_attribute' => 'node_id',
- 'multiplicity' => '1..*' ),
- "contentobject_id" => array( 'name' => "ContentObjectID",
- 'datatype' => 'integer',
- 'default' => 0,
- 'required' => true,
- 'foreign_class' => 'eZContentObject',
- 'foreign_attribute' => 'id',
- 'multiplicity' => '1..*' ),
- 'contentobject_version' => array( 'name' => 'ContentObjectVersion',
- 'datatype' => 'integer',
- 'default' => 0,
- 'required' => true ),
- 'contentobject_is_published' => array( 'name' => 'ContentObjectIsPublished',
- 'datatype' => 'integer',
- 'default' => 0,
- 'required' => true ),
- "depth" => array( 'name' => "Depth",
- 'datatype' => 'integer',
- 'default' => 0,
- 'required' => true ),
- 'sort_field' => array( 'name' => 'SortField',
- 'datatype' => 'integer',
- 'default' => self::SORT_FIELD_PATH,
- 'required' => true ),
- 'sort_order' => array( 'name' => 'SortOrder',
- 'datatype' => 'integer',
- 'default' => self::SORT_ORDER_ASC,
- 'required' => true ),
- 'priority' => array( 'name' => 'Priority',
- 'datatype' => 'integer',
- 'default' => 0,
- 'required' => true ),
- 'modified_subnode' => array( 'name' => 'ModifiedSubNode',
- 'datatype' => 'integer',
- 'default' => 0,
- 'required' => true ),
- "path_string" => array( 'name' => "PathString",
- 'datatype' => 'string',
- 'default' => '',
- 'required' => true ),
- "path_identification_string" => array( 'name' => "PathIdentificationString",
- 'datatype' => 'text',
- 'default' => '',
- 'required' => true ),
- 'remote_id' => array( 'name' => 'RemoteID',
- 'datatype' => 'string',
- 'default' => '',
- 'required' => true ),
- "is_hidden" => array( 'name' => "IsHidden",
- 'datatype' => 'integer',
- 'default' => 0,
- 'required' => true ),
- "is_invisible" => array( 'name' => "IsInvisible",
- 'datatype' => 'integer',
- 'default' => 0,
- 'required' => true ) ),
- "keys" => array( "node_id" ),
- "function_attributes" => array( "name" => "getName",
- 'data_map' => 'dataMap',
- 'remote_id' => 'remoteID', // Note: This overrides remote_id field
- "object" => "object",
- "subtree" => "subTree",
- "children" => "children",
- "children_count" => "childrenCount",
- 'view_count' => 'viewCount',
- 'contentobject_version_object' => 'contentObjectVersionObject',
- 'sort_array' => 'sortArray',
- 'can_read' => 'canRead',
- 'can_pdf' => 'canPdf',
- 'can_create' => 'canCreate',
- 'can_edit' => 'canEdit',
- 'can_hide' => 'canHide',
- 'can_remove' => 'canRemove',
- 'can_move' => 'canMoveFrom',
- 'can_move_from' => 'canMoveFrom',
- 'can_add_location' => 'canAddLocation',
- 'can_remove_location' => 'canRemoveLocation',
- 'can_view_embed' => 'canViewEmbed',
- 'is_main' => 'isMain',
- 'creator' => 'creator',
- "path_with_names" => "pathWithNames",
- "path" => "fetchPath",
- 'path_array' => 'pathArray',
- "parent" => "fetchParent",
- 'url' => 'url',
- 'url_alias' => 'urlAlias',
- 'class_identifier' => 'classIdentifier',
- 'class_name' => 'className',
- 'hidden_invisible_string' => 'hiddenInvisibleString',
- 'hidden_status_string' => 'hiddenStatusString',
- 'classes_js_array' => 'availableClassesJsArray',
- 'is_container' => 'classIsContainer' ),
- "increment_key" => "node_id",
- "class_name" => "eZContentObjectTreeNode",
- "name" => "ezcontentobject_tree" );
- return $definition;
- }
- /*!
- Creates a new tree node and returns it.
- \param $parentNodeID The ID of the parent or \c null if the node is not known yet.
- \param $contentObjectID The ID of the object it points to or \c null if it is not known yet.
- \param $contentObjectVersion The version of the object or \c 0 if not known yet.
- \param $sortField Number describing the field to sort by, or \c 0 if not known yet.
- \param $sortOrder Which way to sort, \c true means ascending while \c false is descending.
- \note The attribute \c remote_id will get an automatic and unique value.
- */
- static function create( $parentNodeID = null, $contentObjectID = null, $contentObjectVersion = 0,
- $sortField = 0, $sortOrder = true )
- {
- $row = array( 'node_id' => null,
- 'main_node_id' => null,
- 'parent_node_id' => $parentNodeID,
- 'contentobject_id' => $contentObjectID,
- 'contentobject_version' => $contentObjectVersion,
- 'contentobject_is_published' => false,
- 'depth' => 1,
- 'path_string' => null,
- 'path_identification_string' => null,
- 'is_hidden' => false,
- 'is_invisible' => false,
- 'sort_field' => $sortField,
- 'sort_order' => $sortOrder,
- 'modified_subnode' => 0,
- 'remote_id' => eZRemoteIdUtility::generate( 'node' ),
- 'priority' => 0 );
- $node = new eZContentObjectTreeNode( $row );
- return $node;
- }
- /*!
- \return a map with all the content object attributes where the keys are the
- attribute identifiers.
- \sa eZContentObject::fetchDataMap
- */
- function dataMap()
- {
- return $this->object()->fetchDataMap( $this->attribute( 'contentobject_version' ) );
- }
- /*!
- Get remote id of content node, the remote ID is often used to synchronise imports and exports.
- If there is no remote ID a new unique one will be generated.
- */
- function remoteID()
- {
- $remoteID = eZPersistentObject::attribute( 'remote_id', true );
- if ( !$remoteID )
- {
- $this->setAttribute( 'remote_id', eZRemoteIdUtility::generate( 'node' ) );
- $this->sync( array( 'remote_id' ) );
- $remoteID = eZPersistentObject::attribute( 'remote_id', true );
- }
- return $remoteID;
- }
- /*!
- \return true if this node is the main node.
- */
- function isMain()
- {
- return $this->NodeID == $this->MainNodeID;
- }
- /*!
- \return the ID of the class attribute with the given ID.
- False is returned if no class/attribute by that identifier is found.
- If multiple classes have the same identifier, the first found is returned.
- */
- static function classAttributeIDByIdentifier( $identifier )
- {
- return eZContentClassAttribute::classAttributeIDByIdentifier( $identifier );
- }
- /*!
- \return the ID of the class with the given ID.
- False is returned if no class by that identifier is found.
- If multiple classes have the same identifier, the first found is returned.
- */
- static function classIDByIdentifier( $identifier )
- {
- return eZContentClass::classIDByIdentifier( $identifier );
- }
- /*!
- \return \c true if the node can be read by the current user.
- \sa checkAccess().
- */
- function canRead( )
- {
- if ( !isset( $this->Permissions["can_read"] ) )
- {
- $this->Permissions["can_read"] = $this->checkAccess( 'read' );
- }
- return ( $this->Permissions["can_read"] == 1 );
- }
- /*!
- \return \c true if the current user can create a pdf of this content object.
- */
- function canPdf( )
- {
- if ( !isset( $this->Permissions["can_pdf"] ) )
- {
- $this->Permissions["can_pdf"] = $this->checkAccess( 'pdf' );
- }
- return ( $this->Permissions["can_pdf"] == 1 );
- }
- /*!
- \return \c true if the node can be viewed as embeded object by the current user.
- \sa checkAccess().
- */
- function canViewEmbed( )
- {
- if ( !isset( $this->Permissions["can_view_embed"] ) )
- {
- $this->Permissions["can_view_embed"] = $this->checkAccess( 'view_embed' );
- }
- return ( $this->Permissions["can_view_embed"] == 1 );
- }
- /*!
- \return \c true if the node can be edited by the current user.
- \sa checkAccess().
- */
- function canEdit( )
- {
- if ( !isset( $this->Permissions["can_edit"] ) )
- {
- $this->Permissions["can_edit"] = $this->checkAccess( 'edit' );
- if ( $this->Permissions["can_edit"] != 1 )
- {
- $user = eZUser::currentUser();
- if ( $user->id() == $this->ContentObject->attribute( 'id' ) )
- {
- $access = $user->hasAccessTo( 'user', 'selfedit' );
- if ( $access['accessWord'] == 'yes' )
- {
- $this->Permissions["can_edit"] = 1;
- }
- }
- }
- }
- return ( $this->Permissions["can_edit"] == 1 );
- }
- /*!
- \return \c true if the node can be hidden by the current user.
- \sa checkAccess().
- */
- function canHide( )
- {
- if ( !isset( $this->Permissions["can_hide"] ) )
- {
- $this->Permissions["can_hide"] = $this->checkAccess( 'hide' );
- }
- return ( $this->Permissions["can_hide"] == 1 );
- }
- /*!
- \return \c true if the current user can create a new node as child of this node.
- \sa checkAccess().
- */
- function canCreate( )
- {
- if ( !isset( $this->Permissions["can_create"] ) )
- {
- $this->Permissions["can_create"] = $this->checkAccess( 'create' );
- }
- return ( $this->Permissions["can_create"] == 1 );
- }
- /*!
- \return \c true if the node can be removed by the current user.
- \sa checkAccess().
- */
- function canRemove( )
- {
- if ( !isset( $this->Permissions["can_remove"] ) )
- {
- $this->Permissions["can_remove"] = $this->checkAccess( 'remove' );
- }
- return ( $this->Permissions["can_remove"] == 1 );
- }
- /*!
- Check if the node can be moved. (actually checks 'edit' and 'remove' permissions)
- \return \c true if the node can be moved by the current user.
- \sa checkAccess().
- \deprecated The function canMove() is preferred since its naming is clearer.
- */
- function canMove()
- {
- return $this->canMoveFrom();
- }
- /*!
- Check if the node can be moved. (actually checks 'edit' and 'remove' permissions)
- \return \c true if the node can be moved by the current user.
- \sa checkAccess().
- */
- function canMoveFrom( )
- {
- if ( !isset( $this->Permissions['can_move_from'] ) )
- {
- $this->Permissions['can_move_from'] = $this->checkAccess( 'edit' ) && $this->checkAccess( 'remove' );
- }
- return ( $this->Permissions['can_move_from'] == 1 );
- }
- /*!
- \return \c true if a node of class \a $classID can be moved to the current node by the current user.
- \sa checkAccess().
- */
- function canMoveTo( $classID = false )
- {
- if ( !isset( $this->Permissions['can_move_to'] ) )
- {
- $this->Permissions['can_move_to'] = $this->checkAccess( 'create', $classID );
- }
- return ( $this->Permissions['can_move_to'] == 1 );
- }
- /*!
- \return \c true if a node can be swaped by the current user.
- \sa checkAccess().
- */
- function canSwap()
- {
- if ( !isset( $this->Permissions['can_swap'] ) )
- {
- $this->Permissions['can_swap'] = $this->checkAccess( 'edit' );
- }
- return ( $this->Permissions['can_swap'] == 1 );
- }
- /*!
- \return \c true if current user can add object locations to current node.
- \sa checkAccess()
- */
- function canAddLocation()
- {
- if ( !isset( $this->Permissions['can_add_location'] ) )
- {
- $this->Permissions['can_add_location'] = $this->checkAccess( 'can_add_location' );
- }
- return ( $this->Permissions['can_add_location'] == 1 );
- }
- /*!
- \return \c true if current user can add object locations to current node.
- */
- function canRemoveLocation()
- {
- if ( !isset( $this->Permissions['can_remove_location'] ) )
- {
- $this->Permissions['can_remove_location'] = $this->checkAccess( 'can_remove_location' );
- }
- return ( $this->Permissions['can_remove_location'] == 1 );
- }
- /*!
- \static
- \returns the sort key for the given classAttributeID.
- int|string is returend. False is returned if unsuccessful.
- */
- static function sortKeyByClassAttributeID( $classAttributeID )
- {
- return eZContentClassAttribute::sortKeyTypeByID( $classAttributeID );
- }
- /*!
- \static
- */
- static function dataTypeByClassAttributeID( $classAttributeID )
- {
- return eZContentClassAttribute::dataTypeByID( $classAttributeID );
- }
- /*!
- Fetches the number of nodes which exists in the system.
- */
- static function fetchListCount()
- {
- $sql = "SELECT count( node_id ) as count FROM ezcontentobject_tree";
- $db = eZDB::instance();
- $rows = $db->arrayQuery( $sql );
- return $rows[0]['count'];
- }
- /*!
- Fetches a list of nodes and returns it. Offset and limitation can be set if needed.
- */
- static function fetchList( $asObject = true, $offset = false, $limit = false )
- {
- $sql = "SELECT * FROM ezcontentobject_tree";
- $parameters = array();
- if ( $offset !== false )
- $parameters['offset'] = $offset;
- if ( $limit !== false )
- $parameters['limit'] = $limit;
- $db = eZDB::instance();
- $rows = $db->arrayQuery( $sql, $parameters );
- $nodes = array();
- if ( $asObject )
- {
- foreach ( $rows as $row )
- {
- $nodes[] = new eZContentObjectTreeNode( $row );
- }
- return $nodes;
- }
- else
- return $rows;
- }
- /*!
- \a static
- */
- static function createSortingSQLStrings( $sortList, $treeTableName = 'ezcontentobject_tree', $allowCustomColumns = false )
- {
- $sortingInfo = array( 'sortCount' => 0,
- 'sortingFields' => " path_string ASC",
- 'attributeJoinCount' => 0,
- 'attributeFromSQL' => "",
- 'attributeTargetSQL' => "",
- 'attributeWhereSQL' => "" );
- if ( $sortList and is_array( $sortList ) and count( $sortList ) > 0 )
- {
- if ( count( $sortList ) > 1 and !is_array( $sortList[0] ) )
- {
- $sortList = array( $sortList );
- }
- $sortingFields = '';
- $sortCount = 0;
- $attributeJoinCount = 0;
- $stateJoinCount = 0;
- $attributeFromSQL = "";
- $attributeWhereSQL = "";
- $datatypeSortingTargetSQL = "";
- foreach ( $sortList as $sortBy )
- {
- if ( is_array( $sortBy ) and count( $sortBy ) > 0 )
- {
- if ( $sortCount > 0 )
- {
- $sortingFields .= ', ';
- }
- $sortField = $sortBy[0];
- switch ( $sortField )
- {
- case 'path':
- {
- $sortingFields .= 'path_string';
- } break;
- case 'path_string':
- {
- $sortingFields .= 'path_identification_string';
- } break;
- case 'published':
- {
- $sortingFields .= 'ezcontentobject.published';
- } break;
- case 'modified':
- {
- $sortingFields .= 'ezcontentobject.modified';
- } break;
- case 'modified_subnode':
- {
- $sortingFields .= 'modified_subnode';
- } break;
- case 'section':
- {
- $sortingFields .= 'ezcontentobject.section_id';
- } break;
- case 'node_id':
- {
- $sortingFields .= $treeTableName . '.node_id';
- } break;
- case 'contentobject_id':
- {
- $sortingFields .= $treeTableName . '.contentobject_id';
- } break;
- case 'depth':
- {
- $sortingFields .= 'depth';
- } break;
- case 'class_identifier':
- {
- $sortingFields .= 'ezcontentclass.identifier';
- } break;
- case 'class_name':
- {
- $classNameFilter = eZContentClassName::sqlFilter();
- $sortingFields .= 'contentclass_name';
- $datatypeSortingTargetSQL .= ", $classNameFilter[nameField] AS contentclass_name";
- $attributeFromSQL .= ", $classNameFilter[from]";
- $attributeWhereSQL .= "$classNameFilter[where] AND ";
- } break;
- case 'priority':
- {
- $sortingFields .= $treeTableName . '.priority';
- } break;
- case 'name':
- {
- $sortingFields .= 'ezcontentobject_name.name';
- } break;
- case 'attribute':
- {
- $classAttributeID = $sortBy[2];
- if ( !is_numeric( $classAttributeID ) )
- $classAttributeID = eZContentObjectTreeNode::classAttributeIDByIdentifier( $classAttributeID );
- $contentAttributeTableAlias = "a$attributeJoinCount";
- $datatypeFromSQL = "ezcontentobject_attribute $contentAttributeTableAlias";
- $datatypeWhereSQL = "
- $contentAttributeTableAlias.contentobject_id = ezcontentobject.id AND
- $contentAttributeTableAlias.contentclassattribute_id = $classAttributeID AND
- $contentAttributeTableAlias.version = ezcontentobject_name.content_version AND";
- $datatypeWhereSQL .= eZContentLanguage::sqlFilter( $contentAttributeTableAlias, 'ezcontentobject' );
- $dataType = eZDataType::create( eZContentObjectTreeNode::dataTypeByClassAttributeID( $classAttributeID ) );
- if( is_object( $dataType ) && $dataType->customSorting() )
- {
- $params = array();
- $params['contentobject_attr_id'] = "$contentAttributeTableAlias.id";
- $params['contentobject_attr_version'] = "$contentAttributeTableAlias.version";
- $params['table_alias_suffix'] = "$attributeJoinCount";
- $sql = $dataType->customSortingSQL( $params );
- $datatypeFromSQL .= ", {$sql['from']}";
- $datatypeWhereSQL .= " AND {$sql['where']}";
- $datatypeSortingFieldSQL = $sql['sorting_field'];
- $datatypeSortingTargetSQL .= ', ' . $sql['sorting_field'];
- }
- else
- {
- // Look up datatype for standard sorting
- $sortKeyType = eZContentObjectTreeNode::sortKeyByClassAttributeID( $classAttributeID );
- switch ( $sortKeyType )
- {
- case 'string':
- {
- $sortKey = 'sort_key_string';
- } break;
- case 'int':
- default:
- {
- $sortKey = 'sort_key_int';
- } break;
- }
- $datatypeSortingFieldSQL = "a$attributeJoinCount.$sortKey";
- $datatypeSortingTargetSQL .= ', ' . $datatypeSortingFieldSQL;
- }
- $sortingFields .= "$datatypeSortingFieldSQL";
- $attributeFromSQL .= ", $datatypeFromSQL";
- $attributeWhereSQL .= "$datatypeWhereSQL AND ";
- $attributeJoinCount++;
- }break;
- case 'state':
- {
- $stateGroupID = $sortBy[2];
- if ( !is_numeric( $stateGroupID ) )
- {
- $stateGroup = eZContentObjectStateGroup::fetchByIdentifier( $stateGroupID );
- if ( $stateGroup )
- {
- $stateGroupID = $stateGroup->attribute( 'id' );
- }
- else
- {
- eZDebug::writeError( "Unknown content object state group '$stateGroupID'" );
- continue 2;
- }
- }
- $stateAlias = "s$stateJoinCount";
- $stateLinkAlias = "sl$stateJoinCount";
- $sortingFields .= "$stateAlias.priority";
- $datatypeSortingTargetSQL .= ", $stateAlias.priority";
- $attributeFromSQL .= ", ezcobj_state $stateAlias, ezcobj_state_link $stateLinkAlias";
- $attributeWhereSQL .= "$stateLinkAlias.contentobject_id=$treeTableName.contentobject_id AND
- $stateLinkAlias.contentobject_state_id=$stateAlias.id AND
- $stateAlias.group_id=$stateGroupID AND ";
- } break;
- default:
- {
- if ( $allowCustomColumns )
- {
- $sortingFields .= $sortField;
- }
- else
- {
- eZDebug::writeWarning( 'Unknown sort field: ' . $sortField, __METHOD__ );
- continue;
- }
- }
- }
- $sortOrder = true; // true is ascending
- if ( isset( $sortBy[1] ) )
- $sortOrder = $sortBy[1];
- $sortingFields .= $sortOrder ? " ASC" : " DESC";
- ++$sortCount;
- }
- }
- $sortingInfo['sortCount'] = $sortCount;
- $sortingInfo['sortingFields'] = $sortingFields;
- $sortingInfo['attributeTargetSQL'] = $datatypeSortingTargetSQL;
- $sortingInfo['attributeJoinCount'] = $attributeJoinCount;
- $sortingInfo['attributeFromSQL'] = $attributeFromSQL;
- $sortingInfo['attributeWhereSQL'] = $attributeWhereSQL;
- }
- return $sortingInfo;
- }
- /*!
- \a static
- */
- static function createClassFilteringSQLString( $classFilterType, &$classFilterArray )
- {
- // Check for class filtering
- $classCondition = '';
- if ( isset( $classFilterType ) &&
- ( $classFilterType == 'include' || $classFilterType == 'exclude' ) &&
- count( $classFilterArray ) > 0 )
- {
- $classCondition = ' ';
- $i = 0;
- $classCount = count( $classFilterArray );
- $classIDArray = array();
- foreach ( $classFilterArray as $classID )
- {
- $originalClassID = $classID;
- // Check if classes are recerenced by identifier
- if ( is_string( $classID ) && !is_numeric( $classID ) )
- {
- $classID = eZContentClass::classIDByIdentifier( $classID );
- }
- if ( is_numeric( $classID ) )
- {
- $classIDArray[] = $classID;
- }
- else
- {
- eZDebugSetting::writeWarning( 'kernel-content-class', "Invalid class identifier in subTree() classfilterarray, classID : " . $originalClassID );
- }
- }
- if ( count( $classIDArray ) > 0 )
- {
- $classCondition .= " ezcontentobject.contentclass_id ";
- if ( $classFilterType == 'include' )
- $classCondition .= " IN ";
- else
- $classCondition .= " NOT IN ";
- $classIDString = implode( ', ', $classIDArray );
- $classCondition .= ' ( ' . $classIDString . ' ) AND';
- }
- else
- {
- if ( count( $classIDArray ) == 0 and count( $classFilterArray ) > 0 and $classFilterType == 'include' )
- {
- $classCondition = false;
- }
- }
- }
- return $classCondition;
- }
- /*!
- \a static
- */
- static function createExtendedAttributeFilterSQLStrings( &$extendedAttributeFilter )
- {
- $filter = array( 'tables' => '',
- 'joins' => '',
- 'columns' => '',
- 'group_by' => '' );
- if ( $extendedAttributeFilter and count( $extendedAttributeFilter ) > 1 )
- {
- $extendedAttributeFilterID = $extendedAttributeFilter['id'];
- $extendedAttributeFilterParams = $extendedAttributeFilter['params'];
- $filterINI = eZINI::instance( 'extendedattributefilter.ini' );
- if ( !$filterINI->hasGroup( $extendedAttributeFilterID ) )
- {
- eZDebug::writeError( "Unable to find configuration for the extended attribute filter '$extendedAttributeFilterID', the filter will be ignored", __METHOD__ );
- return $filter;
- }
- $filterClassName = $filterINI->variable( $extendedAttributeFilterID, 'ClassName' );
- $filterMethodName = $filterINI->variable( $extendedAttributeFilterID, 'MethodName' );
- if ( $filterINI->hasVariable( $extendedAttributeFilterID, 'FileName' ) )
- {
- $filterFile = $filterINI->variable( $extendedAttributeFilterID, 'FileName' );
- if ( $filterINI->hasVariable( $extendedAttributeFilterID, 'ExtensionName' ) )
- {
- $extensionName = $filterINI->variable( $extendedAttributeFilterID, 'ExtensionName' );
- include_once( eZExtension::baseDirectory() . "/$extensionName/$filterFile" );
- }
- else
- {
- include_once( $filterFile );
- }
- }
- if ( !class_exists( $filterClassName, true ) )
- {
- eZDebug::writeError( "Unable to find the PHP class '$filterClassName' associated with the extended attribute filter '$extendedAttributeFilterID', the filter will be ignored", __METHOD__ );
- return $filter;
- }
- $classObject = new $filterClassName();
- $parameterArray = array( $extendedAttributeFilterParams );
- $sqlResult = call_user_func_array( array( $classObject, $filterMethodName ), $parameterArray );
- $filter['tables'] = $sqlResult['tables'];
- $filter['joins'] = $sqlResult['joins'];
- $filter['columns'] = isset( $sqlResult['columns'] ) ? $sqlResult['columns'] : '';
- if( isset( $sqlResult['group_by'] ) )
- $filter['group_by'] = $sqlResult['group_by'];
- }
- return $filter;
- }
- /*!
- \a static
- */
- static function createMainNodeConditionSQLString( $mainNodeOnly )
- {
- // Main node check
- $mainNodeCondition = '';
- if ( isset( $mainNodeOnly ) && $mainNodeOnly === true )
- {
- $mainNodeCondition = 'ezcontentobject_tree.node_id = ezcontentobject_tree.main_node_id AND';
- }
- return $mainNodeCondition;
- }
- /*!
- \a static
- */
- static function createObjectNameFilterConditionSQLString( $filter )
- {
- if ( !$filter )
- return '';
- $db = eZDB::instance();
- if ( $filter == 'others' )
- {
- $alphabet = eZAlphabetOperator::fetchAlphabet();
- $sql = '';
- foreach ( $alphabet as $letter )
- {
- $sql .= " AND ezcontentobject.name NOT LIKE '". $db->escapeString( $letter ) . "%' ";
- }
- return $sql;
- }
- $objectNameFilterSQL = " AND ezcontentobject.name LIKE '" . $db->escapeString( $filter ) ."%'";
- return $objectNameFilterSQL;
- }
- /*!
- \a static
- */
- static function createAttributeFilterSQLStrings( &$attributeFilter, &$sortingInfo = array( 'sortCount' => 0, 'attributeJoinCount' => 0 ) )
- {
- // Check for attribute filtering
- $filterSQL = array( 'from' => '',
- 'where' => '' );
- $totalAttributesFiltersCount = 0;
- $invalidAttributesFiltersCount = 0;
- if ( isset( $attributeFilter ) && $attributeFilter !== false )
- {
- if ( !is_array( $attributeFilter ) )
- {
- eZDebug::writeError( "\$attributeFilter needs to be an array", __METHOD__ );
- return $filterSQL;
- }
- $filterArray = $attributeFilter;
- // Check if first value of array is a string.
- // To check for and/or filtering
- $filterJoinType = 'AND';
- if ( is_string( $filterArray[0] ) )
- {
- if ( strtolower( $filterArray[0] ) == 'or' )
- {
- $filterJoinType = 'OR';
- }
- else if ( strtolower( $filterArray[0] ) == 'and' )
- {
- $filterJoinType = 'AND';
- }
- unset( $filterArray[0] );
- }
- $attibuteFilterJoinSQL = "";
- $filterCount = $sortingInfo['sortCount'];
- $justFilterCount = 0;
- $db = eZDB::instance();
- if ( is_array( $filterArray ) )
- {
- // Handle attribute filters and generate SQL
- $totalAttributesFiltersCount = count( $filterArray );
- foreach ( $filterArray as $filter )
- {
- $isFilterValid = true; // by default assumes that filter is valid
- $filterAttributeID = $filter[0];
- $filterType = $filter[1];
- $filterValue = is_array( $filter[2] ) ? '' : $db->escapeString( $filter[2] );
- $useAttributeFilter = false;
- switch ( $filterAttributeID )
- {
- case 'path':
- {
- $filterField = 'path_string';
- } break;
- case 'published':
- {
- $filterField = 'ezcontentobject.published';
- } break;
- case 'modified':
- {
- $filterField = 'ezcontentobject.modified';
- } break;
- case 'modified_subnode':
- {
- $filterField = 'modified_subnode';
- } break;
- case 'node_id':
- {
- $filterField = 'ezcontentobject_tree.node_id';
- } break;
- case 'contentobject_id':
- {
- $filterField = 'ezcontentobject_tree.contentobject_id';
- } break;
- case 'section':
- {
- $filterField = 'ezcontentobject.section_id';
- } break;
- case 'state':
- {
- // state only supports =, !=, in, and not_in
- // other operators do not make any sense in this context
- $hasFilterOperator = true;
- switch ( $filterType )
- {
- case '=' :
- case '!=':
- {
- $subQueryCondition = 'contentobject_state_id = ' . (int) $filter[2];
- $filterOperator = ( $filterType == '=' ? 'IN' : 'NOT IN' );
- } break;
- case 'in':
- case 'not_in' :
- {
- if ( is_array( $filter[2] ) )
- {
- $subQueryCondition = $db->generateSQLINStatement( $filter[2], 'contentobject_state_id', false, false, 'int' );
- $filterOperator = ( $filterType == 'in' ? 'IN' : 'NOT IN' );
- }
- else
- {
- $hasFilterOperator = false;
- }
- } break;
- default :
- {
- $hasFilterOperator = false;
- eZDebug::writeError( "Unknown attribute filter type for state: $filterType", __METHOD__ );
- } break;
- }
- if ( $hasFilterOperator )
- {
- if ( ( $filterCount - $sortingInfo['sortCount'] ) > 0 )
- $attibuteFilterJoinSQL .= " $filterJoinType ";
- $attibuteFilterJoinSQL .= "ezcontentobject.id $filterOperator (SELECT contentobject_id FROM ezcobj_state_link WHERE $subQueryCondition)";
- $filterCount++;
- $justFilterCount++;
- }
- continue 2;
- } break;
- case 'depth':
- {
- $filterField = 'depth';
- } break;
- case 'class_identifier':
- {
- $filterField = 'ezcontentclass.identifier';
- } break;
- case 'class_name':
- {
- $classNameFilter = eZContentClassName::sqlFilter();
- $filterField = $classNameFilter['nameField'];
- $filterSQL['from'] .= ", $classNameFilter[from]";
- $filterSQL['where'] .= "$classNameFilter[where] AND ";
- } break;
- case 'priority':
- {
- $filterField = 'ezcontentobject_tree.priority';
- } break;
- case 'name':
- {
- $filterField = 'ezcontentobject_name.name';
- } break;
- case 'owner':
- {
- $filterField = 'ezcontentobject.owner_id';
- } break;
- case 'visibility':
- {
- $filterValue = ( $filterValue == '1' ) ? 0 : 1;
- $filterField = 'ezcontentobject_tree.is_invisible';
- } break;
- default:
- {
- $useAttributeFilter = true;
- } break;
- }
- if ( $useAttributeFilter )
- {
- if ( !is_numeric( $filterAttributeID ) )
- $filterAttributeID = eZContentObjectTreeNode::classAttributeIDByIdentifier( $filterAttributeID );
- if ( $filterAttributeID === false )
- {
- $isFilterValid = false;
- if( $filterJoinType === 'AND' )
- {
- // go out
- $invalidAttributesFiltersCount = $totalAttributesFiltersCount;
- break;
- }
- ++$invalidAttributesFiltersCount;
- }
- else
- {
- // Check datatype for filtering
- $filterDataType = eZContentObjectTreeNode::sortKeyByClassAttributeID( $filterAttributeID );
- if ( $filterDataType === false )
- {
- $isFilterValid = false;
- if( $filterJoinType === 'AND' )
- {
- // go out
- $invalidAttributesFiltersCount = $totalAttributesFiltersCount;
- break;
- }
- // check next filter
- ++$invalidAttributesFiltersCount;
- }
- else
- {
- $sortKey = false;
- if ( $filterDataType == 'string' )
- {
- $sortKey = 'sort_key_string';
- }
- else
- {
- $sortKey = 'sort_key_int';
- }
- $filterField = "a$filterCount.$sortKey";
- // Use the same joins as we do when sorting,
- // if more attributes are filtered by we will append them
- if ( $filterCount >= $sortingInfo['attributeJoinCount'] )
- {
- $filterSQL['from'] .= ", ezcontentobject_attribute a$filterCount ";
- }
- $filterSQL['where'] .= "
- a$filterCount.contentobject_id = ezcontentobject.id AND
- a$filterCount.contentclassattribute_id = $filterAttributeID AND
- a$filterCount.version = ezcontentobject_name.content_version AND ";
- $filterSQL['where'] .= eZContentLanguage::sqlFilter( "a$filterCount", 'ezcontentobject' ). ' AND ';
- }
- }
- }
- if ( $isFilterValid )
- {
- $hasFilterOperator = true;
- // Controls quotes around filter value, some filters do this manually
- $noQuotes = false;
- // Controls if $f…
Large files files are truncated, but you can click here to view the full file